From 4b0ee92f91c75dc0a273ff24e4d9884c38aa379f Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Fri, 16 Jun 2017 18:50:42 +0000 Subject: [PATCH] [D3D8][D3D9][DDRAW][WINED3D] Sync with Wine Staging 2.9. This work couldn't have been committed without Sebastian Gasiorek's work on CORE-11331 so thanks again! Dedicated to Daniel. CORE-13362 svn path=/trunk/; revision=75061 --- reactos/dll/directx/wine/d3d8/buffer.c | 24 +- reactos/dll/directx/wine/d3d8/d3d8.spec | 2 +- reactos/dll/directx/wine/d3d8/d3d8_main.c | 80 +- reactos/dll/directx/wine/d3d8/d3d8_private.h | 68 +- reactos/dll/directx/wine/d3d8/device.c | 416 +- reactos/dll/directx/wine/d3d8/directx.c | 50 +- reactos/dll/directx/wine/d3d8/shader.c | 14 +- reactos/dll/directx/wine/d3d8/surface.c | 58 +- reactos/dll/directx/wine/d3d8/swapchain.c | 7 +- reactos/dll/directx/wine/d3d8/texture.c | 75 +- .../dll/directx/wine/d3d8/vertexdeclaration.c | 4 +- reactos/dll/directx/wine/d3d8/volume.c | 17 +- reactos/dll/directx/wine/d3d9/CMakeLists.txt | 2 +- reactos/dll/directx/wine/d3d9/buffer.c | 24 +- reactos/dll/directx/wine/d3d9/d3d9_private.h | 95 +- reactos/dll/directx/wine/d3d9/device.c | 597 +- reactos/dll/directx/wine/d3d9/directx.c | 115 +- reactos/dll/directx/wine/d3d9/query.c | 44 +- reactos/dll/directx/wine/d3d9/shader.c | 14 +- reactos/dll/directx/wine/d3d9/surface.c | 89 +- reactos/dll/directx/wine/d3d9/swapchain.c | 20 +- reactos/dll/directx/wine/d3d9/texture.c | 125 +- .../dll/directx/wine/d3d9/vertexdeclaration.c | 4 +- reactos/dll/directx/wine/d3d9/volume.c | 17 +- reactos/dll/directx/wine/ddraw/ddraw.c | 205 +- reactos/dll/directx/wine/ddraw/ddraw.spec | 2 +- .../dll/directx/wine/ddraw/ddraw_private.h | 33 +- reactos/dll/directx/wine/ddraw/device.c | 672 +- .../dll/directx/wine/ddraw/executebuffer.c | 402 +- reactos/dll/directx/wine/ddraw/main.c | 150 +- reactos/dll/directx/wine/ddraw/palette.c | 26 +- reactos/dll/directx/wine/ddraw/surface.c | 557 +- reactos/dll/directx/wine/ddraw/utils.c | 92 +- reactos/dll/directx/wine/ddraw/vertexbuffer.c | 228 +- reactos/dll/directx/wine/ddraw/viewport.c | 145 +- .../dll/directx/wine/wined3d/CMakeLists.txt | 1 - .../directx/wine/wined3d/arb_program_shader.c | 1373 +- .../wine/wined3d/ati_fragment_shader.c | 33 +- reactos/dll/directx/wine/wined3d/buffer.c | 1409 +- reactos/dll/directx/wine/wined3d/context.c | 2137 ++- reactos/dll/directx/wine/wined3d/cs.c | 4500 +++---- reactos/dll/directx/wine/wined3d/device.c | 3151 ++--- reactos/dll/directx/wine/wined3d/directx.c | 1412 +- reactos/dll/directx/wine/wined3d/drawprim.c | 1050 +- .../dll/directx/wine/wined3d/glsl_shader.c | 5752 ++++++-- .../wine/wined3d/nvidia_texture_shader.c | 6 +- reactos/dll/directx/wine/wined3d/palette.c | 7 +- reactos/dll/directx/wine/wined3d/query.c | 1661 +-- reactos/dll/directx/wine/wined3d/resource.c | 773 +- reactos/dll/directx/wine/wined3d/sampler.c | 121 +- reactos/dll/directx/wine/wined3d/shader.c | 1878 ++- reactos/dll/directx/wine/wined3d/shader_sm1.c | 93 +- reactos/dll/directx/wine/wined3d/shader_sm4.c | 1482 +- reactos/dll/directx/wine/wined3d/state.c | 934 +- reactos/dll/directx/wine/wined3d/stateblock.c | 326 +- reactos/dll/directx/wine/wined3d/surface.c | 5899 +++----- reactos/dll/directx/wine/wined3d/swapchain.c | 989 +- reactos/dll/directx/wine/wined3d/texture.c | 3168 ++++- reactos/dll/directx/wine/wined3d/utils.c | 1616 ++- .../directx/wine/wined3d/vertexdeclaration.c | 29 +- reactos/dll/directx/wine/wined3d/view.c | 895 +- reactos/dll/directx/wine/wined3d/volume.c | 948 -- reactos/dll/directx/wine/wined3d/wined3d.spec | 111 +- reactos/dll/directx/wine/wined3d/wined3d_gl.h | 43 +- .../dll/directx/wine/wined3d/wined3d_main.c | 119 +- .../directx/wine/wined3d/wined3d_private.h | 2230 ++-- reactos/media/doc/README.WINE | 8 +- reactos/sdk/include/reactos/wine/wgl.h | 11130 ++++++++-------- reactos/sdk/include/reactos/wine/wgl_driver.h | 55 +- reactos/sdk/include/reactos/wine/wined3d.h | 573 +- 70 files changed, 32329 insertions(+), 28056 deletions(-) delete mode 100644 reactos/dll/directx/wine/wined3d/volume.c diff --git a/reactos/dll/directx/wine/d3d8/buffer.c b/reactos/dll/directx/wine/d3d8/buffer.c index a5786cca04a..d778e58360d 100644 --- a/reactos/dll/directx/wine/d3d8/buffer.c +++ b/reactos/dll/directx/wine/d3d8/buffer.c @@ -164,7 +164,7 @@ static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_preload(buffer->wined3d_buffer); + wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer)); wined3d_mutex_unlock(); } @@ -179,14 +179,20 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT BYTE **data, DWORD flags) { struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; HRESULT hr; TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n", iface, offset, size, data, flags); + wined3d_box.left = offset; + wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), + 0, &wined3d_map_desc, &wined3d_box, flags); wined3d_mutex_unlock(); + *data = wined3d_map_desc.data; return hr; } @@ -198,7 +204,7 @@ static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_unmap(buffer->wined3d_buffer); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); wined3d_mutex_unlock(); return D3D_OK; @@ -441,7 +447,7 @@ static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_preload(buffer->wined3d_buffer); + wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer)); wined3d_mutex_unlock(); } @@ -456,14 +462,20 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o BYTE **data, DWORD flags) { struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; HRESULT hr; TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n", iface, offset, size, data, flags); + wined3d_box.left = offset; + wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), + 0, &wined3d_map_desc, &wined3d_box, flags); wined3d_mutex_unlock(); + *data = wined3d_map_desc.data; return hr; } @@ -475,7 +487,7 @@ static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_unmap(buffer->wined3d_buffer); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); wined3d_mutex_unlock(); return D3D_OK; diff --git a/reactos/dll/directx/wine/d3d8/d3d8.spec b/reactos/dll/directx/wine/d3d8/d3d8.spec index 4bad85023af..4f125a9c1c1 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8.spec +++ b/reactos/dll/directx/wine/d3d8/d3d8.spec @@ -1,5 +1,5 @@ @ stdcall D3D8GetSWInfo() @ stdcall DebugSetMute() @ stdcall Direct3DCreate8(long) -@ stdcall ValidatePixelShader(ptr long long ptr) +@ stdcall ValidatePixelShader(ptr ptr long ptr) @ stdcall ValidateVertexShader(ptr ptr ptr long ptr) diff --git a/reactos/dll/directx/wine/d3d8/d3d8_main.c b/reactos/dll/directx/wine/d3d8/d3d8_main.c index 144817a545b..a8ad29b3b3d 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_main.c +++ b/reactos/dll/directx/wine/d3d8/d3d8_main.c @@ -53,75 +53,73 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version) /*********************************************************************** * ValidateVertexShader (D3D8.@) - * - * I've seen reserved1 and reserved2 always passed as 0's - * bool seems always passed as 0 or 1, but other values work as well... - * toto result? */ -HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto) +HRESULT WINAPI ValidateVertexShader(DWORD *vertexshader, DWORD *reserved1, DWORD *reserved2, + BOOL return_error, char **errors) { - HRESULT ret; - static BOOL warned; + const char *message = ""; + HRESULT hr = E_FAIL; - if (TRACE_ON(d3d8) || !warned) { - FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto); - warned = TRUE; - } + TRACE("(%p %p %p %d %p): semi-stub\n", vertexshader, reserved1, reserved2, return_error, errors); - if (!vertexshader) - return E_FAIL; + if (!vertexshader) + { + message = "(Global Validation Error) Version Token: Code pointer cannot be NULL.\n"; + goto done; + } - if (reserved1 || reserved2) - return E_FAIL; - - switch(*vertexshader) { + switch (*vertexshader) + { case 0xFFFE0101: case 0xFFFE0100: - ret=S_OK; + hr = S_OK; break; + default: WARN("Invalid shader version token %#x.\n", *vertexshader); - ret=E_FAIL; - } + message = "(Global Validation Error) Version Token: Unsupported vertex shader version.\n"; + } - return ret; +done: + if (!return_error) message = ""; + if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) + strcpy(*errors, message); + + return hr; } /*********************************************************************** * ValidatePixelShader (D3D8.@) - * - * PARAMS - * toto result? */ -HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto) +HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL return_error, char **errors) { - HRESULT ret; - static BOOL warned; + const char *message = ""; + HRESULT hr = E_FAIL; - if (TRACE_ON(d3d8) || !warned) { - FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto); - warned = TRUE; - } + TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, return_error, errors); - if (!pixelshader) - return E_FAIL; + if (!pixelshader) + return E_FAIL; - if (reserved1) - return E_FAIL; - - switch(*pixelshader) { + switch (*pixelshader) + { case 0xFFFF0100: case 0xFFFF0101: case 0xFFFF0102: case 0xFFFF0103: case 0xFFFF0104: - ret=S_OK; + hr = S_OK; break; default: WARN("Invalid shader version token %#x.\n", *pixelshader); - ret=E_FAIL; - } - return ret; + message = "(Global Validation Error) Version Token: Unsupported pixel shader version.\n"; + } + + if (!return_error) message = ""; + if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) + strcpy(*errors, message); + + return hr; } void d3d8_resource_cleanup(struct d3d8_resource *resource) diff --git a/reactos/dll/directx/wine/d3d8/d3d8_private.h b/reactos/dll/directx/wine/d3d8/d3d8_private.h index 7d8a487f6d0..a85e2995cbe 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_private.h +++ b/reactos/dll/directx/wine/d3d8/d3d8_private.h @@ -45,69 +45,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d8); #include #include +#define D3DPRESENTFLAGS_MASK 0x00000fffu + /* CreateVertexShader can return > 0xFFFF */ #define VS_HIGHESTFIXEDFXF 0xF0000000 -/* =========================================================================== - Macros - =========================================================================== */ -/* Not nice, but it lets wined3d support different versions of directx */ -#define WINECAPSTOD3D8CAPS(_pD3D8Caps, _pWineCaps) \ - _pD3D8Caps->DeviceType = (D3DDEVTYPE) _pWineCaps->DeviceType; \ - _pD3D8Caps->AdapterOrdinal = _pWineCaps->AdapterOrdinal; \ - _pD3D8Caps->Caps = _pWineCaps->Caps; \ - _pD3D8Caps->Caps2 = _pWineCaps->Caps2; \ - _pD3D8Caps->Caps3 = _pWineCaps->Caps3; \ - _pD3D8Caps->PresentationIntervals = _pWineCaps->PresentationIntervals; \ - _pD3D8Caps->CursorCaps = _pWineCaps->CursorCaps; \ - _pD3D8Caps->DevCaps = _pWineCaps->DevCaps; \ - _pD3D8Caps->PrimitiveMiscCaps = _pWineCaps->PrimitiveMiscCaps; \ - _pD3D8Caps->RasterCaps = _pWineCaps->RasterCaps; \ - _pD3D8Caps->ZCmpCaps = _pWineCaps->ZCmpCaps; \ - _pD3D8Caps->SrcBlendCaps = _pWineCaps->SrcBlendCaps; \ - _pD3D8Caps->DestBlendCaps = _pWineCaps->DestBlendCaps; \ - _pD3D8Caps->AlphaCmpCaps = _pWineCaps->AlphaCmpCaps; \ - _pD3D8Caps->ShadeCaps = _pWineCaps->ShadeCaps; \ - _pD3D8Caps->TextureCaps = _pWineCaps->TextureCaps; \ - _pD3D8Caps->TextureFilterCaps = _pWineCaps->TextureFilterCaps; \ - _pD3D8Caps->CubeTextureFilterCaps = _pWineCaps->CubeTextureFilterCaps; \ - _pD3D8Caps->VolumeTextureFilterCaps = _pWineCaps->VolumeTextureFilterCaps; \ - _pD3D8Caps->TextureAddressCaps = _pWineCaps->TextureAddressCaps; \ - _pD3D8Caps->VolumeTextureAddressCaps = _pWineCaps->VolumeTextureAddressCaps; \ - _pD3D8Caps->LineCaps = _pWineCaps->LineCaps; \ - _pD3D8Caps->MaxTextureWidth = _pWineCaps->MaxTextureWidth; \ - _pD3D8Caps->MaxTextureHeight = _pWineCaps->MaxTextureHeight; \ - _pD3D8Caps->MaxVolumeExtent = _pWineCaps->MaxVolumeExtent; \ - _pD3D8Caps->MaxTextureRepeat = _pWineCaps->MaxTextureRepeat; \ - _pD3D8Caps->MaxTextureAspectRatio = _pWineCaps->MaxTextureAspectRatio; \ - _pD3D8Caps->MaxAnisotropy = _pWineCaps->MaxAnisotropy; \ - _pD3D8Caps->MaxVertexW = _pWineCaps->MaxVertexW; \ - _pD3D8Caps->GuardBandLeft = _pWineCaps->GuardBandLeft; \ - _pD3D8Caps->GuardBandTop = _pWineCaps->GuardBandTop; \ - _pD3D8Caps->GuardBandRight = _pWineCaps->GuardBandRight; \ - _pD3D8Caps->GuardBandBottom = _pWineCaps->GuardBandBottom; \ - _pD3D8Caps->ExtentsAdjust = _pWineCaps->ExtentsAdjust; \ - _pD3D8Caps->StencilCaps = _pWineCaps->StencilCaps; \ - _pD3D8Caps->FVFCaps = _pWineCaps->FVFCaps; \ - _pD3D8Caps->TextureOpCaps = _pWineCaps->TextureOpCaps; \ - _pD3D8Caps->MaxTextureBlendStages = _pWineCaps->MaxTextureBlendStages; \ - _pD3D8Caps->MaxSimultaneousTextures = _pWineCaps->MaxSimultaneousTextures; \ - _pD3D8Caps->VertexProcessingCaps = _pWineCaps->VertexProcessingCaps; \ - _pD3D8Caps->MaxActiveLights = _pWineCaps->MaxActiveLights; \ - _pD3D8Caps->MaxUserClipPlanes = _pWineCaps->MaxUserClipPlanes; \ - _pD3D8Caps->MaxVertexBlendMatrices = _pWineCaps->MaxVertexBlendMatrices; \ - _pD3D8Caps->MaxVertexBlendMatrixIndex = _pWineCaps->MaxVertexBlendMatrixIndex; \ - _pD3D8Caps->MaxPointSize = _pWineCaps->MaxPointSize; \ - _pD3D8Caps->MaxPrimitiveCount = _pWineCaps->MaxPrimitiveCount; \ - _pD3D8Caps->MaxVertexIndex = _pWineCaps->MaxVertexIndex; \ - _pD3D8Caps->MaxStreams = _pWineCaps->MaxStreams; \ - _pD3D8Caps->MaxStreamStride = _pWineCaps->MaxStreamStride; \ - _pD3D8Caps->VertexShaderVersion = _pWineCaps->VertexShaderVersion; \ - _pD3D8Caps->MaxVertexShaderConst = _pWineCaps->MaxVertexShaderConst; \ - _pD3D8Caps->PixelShaderVersion = _pWineCaps->PixelShaderVersion; \ - _pD3D8Caps->MaxPixelShaderValue = _pWineCaps->PixelShader1xMaxValue; - -void fixup_caps(WINED3DCAPS *pWineCaps) DECLSPEC_HIDDEN; +void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN; struct d3d8 { @@ -249,7 +192,10 @@ struct d3d8_surface struct d3d8_texture *texture; }; -struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN; +struct wined3d_rendertarget_view *d3d8_surface_acquire_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN; +struct d3d8_device *d3d8_surface_get_device(const struct d3d8_surface *surface) DECLSPEC_HIDDEN; +void d3d8_surface_release_rendertarget_view(struct d3d8_surface *surface, + struct wined3d_rendertarget_view *rtv) DECLSPEC_HIDDEN; void surface_init(struct d3d8_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN; diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 7bf69bb990c..5dbfe174f9f 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -70,7 +70,6 @@ D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8; case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4; case WINED3DFMT_D16_UNORM: return D3DFMT_D16; - case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA; case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16; case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32; default: @@ -121,18 +120,17 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM; case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM; case D3DFMT_D16: return WINED3DFMT_D16_UNORM; - case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA; case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT; case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT; default: - FIXME("Unhandled D3DFORMAT %#x\n", format); + FIXME("Unhandled D3DFORMAT %#x.\n", format); return WINED3DFMT_UNKNOWN; } } static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) { - switch(primitive_type) + switch (primitive_type) { case D3DPT_POINTLIST: return primitive_count; @@ -151,7 +149,7 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U return primitive_count + 2; default: - FIXME("Unhandled primitive type %#x\n", primitive_type); + FIXME("Unhandled primitive type %#x.\n", primitive_type); return 0; } } @@ -170,7 +168,7 @@ static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil; present_parameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); - present_parameters->Flags = swapchain_desc->flags; + present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval; } @@ -204,14 +202,88 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil; swapchain_desc->auto_depth_stencil_format = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat); - swapchain_desc->flags = present_parameters->Flags; + swapchain_desc->flags + = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; + if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) + FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK); + return TRUE; } +void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) +{ + caps->DeviceType = (D3DDEVTYPE)wined3d_caps->DeviceType; + caps->AdapterOrdinal = wined3d_caps->AdapterOrdinal; + caps->Caps = wined3d_caps->Caps; + caps->Caps2 = wined3d_caps->Caps2; + caps->Caps3 = wined3d_caps->Caps3; + caps->PresentationIntervals = wined3d_caps->PresentationIntervals; + caps->CursorCaps = wined3d_caps->CursorCaps; + caps->DevCaps = wined3d_caps->DevCaps; + caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; + caps->RasterCaps = wined3d_caps->RasterCaps; + caps->ZCmpCaps = wined3d_caps->ZCmpCaps; + caps->SrcBlendCaps = wined3d_caps->SrcBlendCaps; + caps->DestBlendCaps = wined3d_caps->DestBlendCaps; + caps->AlphaCmpCaps = wined3d_caps->AlphaCmpCaps; + caps->ShadeCaps = wined3d_caps->ShadeCaps; + caps->TextureCaps = wined3d_caps->TextureCaps; + caps->TextureFilterCaps = wined3d_caps->TextureFilterCaps; + caps->CubeTextureFilterCaps = wined3d_caps->CubeTextureFilterCaps; + caps->VolumeTextureFilterCaps = wined3d_caps->VolumeTextureFilterCaps; + caps->TextureAddressCaps = wined3d_caps->TextureAddressCaps; + caps->VolumeTextureAddressCaps = wined3d_caps->VolumeTextureAddressCaps; + caps->LineCaps = wined3d_caps->LineCaps; + caps->MaxTextureWidth = wined3d_caps->MaxTextureWidth; + caps->MaxTextureHeight = wined3d_caps->MaxTextureHeight; + caps->MaxVolumeExtent = wined3d_caps->MaxVolumeExtent; + caps->MaxTextureRepeat = wined3d_caps->MaxTextureRepeat; + caps->MaxTextureAspectRatio = wined3d_caps->MaxTextureAspectRatio; + caps->MaxAnisotropy = wined3d_caps->MaxAnisotropy; + caps->MaxVertexW = wined3d_caps->MaxVertexW; + caps->GuardBandLeft = wined3d_caps->GuardBandLeft; + caps->GuardBandTop = wined3d_caps->GuardBandTop; + caps->GuardBandRight = wined3d_caps->GuardBandRight; + caps->GuardBandBottom = wined3d_caps->GuardBandBottom; + caps->ExtentsAdjust = wined3d_caps->ExtentsAdjust; + caps->StencilCaps = wined3d_caps->StencilCaps; + caps->FVFCaps = wined3d_caps->FVFCaps; + caps->TextureOpCaps = wined3d_caps->TextureOpCaps; + caps->MaxTextureBlendStages = wined3d_caps->MaxTextureBlendStages; + caps->MaxSimultaneousTextures = wined3d_caps->MaxSimultaneousTextures; + caps->VertexProcessingCaps = wined3d_caps->VertexProcessingCaps; + caps->MaxActiveLights = wined3d_caps->MaxActiveLights; + caps->MaxUserClipPlanes = wined3d_caps->MaxUserClipPlanes; + caps->MaxVertexBlendMatrices = wined3d_caps->MaxVertexBlendMatrices; + caps->MaxVertexBlendMatrixIndex = wined3d_caps->MaxVertexBlendMatrixIndex; + caps->MaxPointSize = wined3d_caps->MaxPointSize; + caps->MaxPrimitiveCount = wined3d_caps->MaxPrimitiveCount; + caps->MaxVertexIndex = wined3d_caps->MaxVertexIndex; + caps->MaxStreams = wined3d_caps->MaxStreams; + caps->MaxStreamStride = wined3d_caps->MaxStreamStride; + caps->VertexShaderVersion = wined3d_caps->VertexShaderVersion; + caps->MaxVertexShaderConst = wined3d_caps->MaxVertexShaderConst; + caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; + caps->MaxPixelShaderValue = wined3d_caps->PixelShader1xMaxValue; + + /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */ + if (caps->PixelShaderVersion) + caps->PixelShaderVersion = D3DPS_VERSION(1, 4); + else + caps->PixelShaderVersion = D3DPS_VERSION(0, 0); + if (caps->VertexShaderVersion) + caps->VertexShaderVersion = D3DVS_VERSION(1, 1); + else + caps->VertexShaderVersion = D3DVS_VERSION(0, 0); + caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); + + caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; +} + /* Handle table functions */ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type) { @@ -443,7 +515,7 @@ static HRESULT WINAPI d3d8_device_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *caps) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - WINED3DCAPS *wined3d_caps; + WINED3DCAPS wined3d_caps; HRESULT hr; TRACE("iface %p, caps %p.\n", iface, caps); @@ -451,16 +523,11 @@ static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS if (!caps) return D3DERR_INVALIDCALL; - if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps)))) - return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */ - wined3d_mutex_lock(); - hr = wined3d_device_get_device_caps(device->wined3d_device, wined3d_caps); + hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); wined3d_mutex_unlock(); - fixup_caps(wined3d_caps); - WINECAPSTOD3D8CAPS(caps, wined3d_caps) - HeapFree(GetProcessHeap(), 0, wined3d_caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps); return hr; } @@ -600,44 +667,34 @@ static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *if static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) { struct wined3d_resource_desc desc; + IDirect3DBaseTexture8 *texture; + struct d3d8_surface *surface; + IUnknown *parent; wined3d_resource_get_desc(resource, &desc); - if (desc.pool == WINED3D_POOL_DEFAULT) + if (desc.pool != WINED3D_POOL_DEFAULT) + return D3D_OK; + + if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) { - struct d3d8_surface *surface; - - if (desc.resource_type == WINED3D_RTYPE_TEXTURE_2D) - { - IUnknown *parent = wined3d_resource_get_parent(resource); - IDirect3DBaseTexture8 *texture; - - if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture))) - { - IDirect3DBaseTexture8_Release(texture); - WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); - return D3DERR_DEVICELOST; - } - - return D3D_OK; - } - - if (desc.resource_type != WINED3D_RTYPE_SURFACE) - { - WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); - return D3DERR_DEVICELOST; - } - - surface = wined3d_resource_get_parent(resource); - if (surface->resource.refcount) - { - WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource); - return D3DERR_DEVICELOST; - } - - WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource); + WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); + return D3DERR_DEVICELOST; } - return D3D_OK; + parent = wined3d_resource_get_parent(resource); + if (parent && SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture))) + { + IDirect3DBaseTexture8_Release(texture); + WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); + return D3DERR_DEVICELOST; + } + + surface = wined3d_texture_get_sub_resource_parent(wined3d_texture_from_resource(resource), 0); + if (!surface->resource.refcount) + return D3D_OK; + + WARN("Surface %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface); + return D3DERR_DEVICELOST; } static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, @@ -786,6 +843,9 @@ static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface, TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, width, height, levels, usage, format, pool, texture); + if (!format) + return D3DERR_INVALIDCALL; + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -816,6 +876,9 @@ static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface, TRACE("iface %p, width %u, height %u, depth %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, width, height, depth, levels, usage, format, pool, texture); + if (!format) + return D3DERR_INVALIDCALL; + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -845,6 +908,9 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", iface, edge_length, levels, usage, format, pool, texture); + if (!format) + return D3DERR_INVALIDCALL; + *texture = NULL; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) @@ -929,8 +995,8 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width struct wined3d_texture *texture; HRESULT hr; - TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p,\n" - "\tusage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", + TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p, " + "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", device, width, height, format, flags, surface, usage, pool, multisample_type, multisample_quality); @@ -948,7 +1014,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, - 1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) + 1, 1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); @@ -976,6 +1042,9 @@ static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UI TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n", iface, width, height, format, multisample_type, lockable, surface); + if (!format) + return D3DERR_INVALIDCALL; + *surface = NULL; if (lockable) flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; @@ -993,6 +1062,9 @@ static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *if TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n", iface, width, height, format, multisample_type, surface); + if (!format) + return D3DERR_INVALIDCALL; + *surface = NULL; /* TODO: Verify that Discard is false */ @@ -1022,8 +1094,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, struct d3d8_surface *src = unsafe_impl_from_IDirect3DSurface8(src_surface); struct d3d8_surface *dst = unsafe_impl_from_IDirect3DSurface8(dst_surface); enum wined3d_format_id src_format, dst_format; - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *wined3d_resource; + struct wined3d_sub_resource_desc wined3d_desc; UINT src_w, src_h; TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n", @@ -1033,8 +1104,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, * destination texture is in WINED3D_POOL_DEFAULT. */ wined3d_mutex_lock(); - wined3d_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx); - wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &wined3d_desc); if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) { WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface); @@ -1045,8 +1115,7 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, src_w = wined3d_desc.width; src_h = wined3d_desc.height; - wined3d_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx); - wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &wined3d_desc); if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) { WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface); @@ -1154,38 +1223,42 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_surface *rt_impl = unsafe_impl_from_IDirect3DSurface8(render_target); struct d3d8_surface *ds_impl = unsafe_impl_from_IDirect3DSurface8(depth_stencil); - struct wined3d_rendertarget_view *original_dsv; + struct wined3d_rendertarget_view *original_dsv, *rtv; HRESULT hr = D3D_OK; TRACE("iface %p, render_target %p, depth_stencil %p.\n", iface, render_target, depth_stencil); + if (rt_impl && d3d8_surface_get_device(rt_impl) != device) + { + WARN("Render target surface does not match device.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (ds_impl) { + struct wined3d_sub_resource_desc ds_desc, rt_desc; struct wined3d_rendertarget_view *original_rtv; - struct wined3d_resource_desc ds_desc, rt_desc; - struct wined3d_resource *wined3d_resource; struct d3d8_surface *original_surface; /* If no render target is passed in check the size against the current RT */ if (!render_target) { - if (!(original_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) { wined3d_mutex_unlock(); return D3DERR_NOTFOUND; } original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv); - wined3d_resource = wined3d_texture_get_sub_resource(original_surface->wined3d_texture, original_surface->sub_resource_idx); + wined3d_texture_get_sub_resource_desc(original_surface->wined3d_texture, + original_surface->sub_resource_idx, &rt_desc); } else - wined3d_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx); - wined3d_resource_get_desc(wined3d_resource, &rt_desc); + wined3d_texture_get_sub_resource_desc(rt_impl->wined3d_texture, + rt_impl->sub_resource_idx, &rt_desc); - wined3d_resource = wined3d_texture_get_sub_resource(ds_impl->wined3d_texture, ds_impl->sub_resource_idx); - wined3d_resource_get_desc(wined3d_resource, &ds_desc); + wined3d_texture_get_sub_resource_desc(ds_impl->wined3d_texture, ds_impl->sub_resource_idx, &ds_desc); if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height) { @@ -1199,16 +1272,17 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, WARN("Multisample settings do not match, returning D3DERR_INVALIDCALL\n"); wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; - } } original_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device); - wined3d_device_set_depth_stencil_view(device->wined3d_device, - ds_impl ? d3d8_surface_get_rendertarget_view(ds_impl) : NULL); - if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0, - d3d8_surface_get_rendertarget_view(rt_impl), TRUE))) + rtv = ds_impl ? d3d8_surface_acquire_rendertarget_view(ds_impl) : NULL; + wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); + d3d8_surface_release_rendertarget_view(ds_impl, rtv); + rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; + if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0, rtv, TRUE))) wined3d_device_set_depth_stencil_view(device->wined3d_device, original_dsv); + d3d8_surface_release_rendertarget_view(rt_impl, rtv); wined3d_mutex_unlock(); @@ -1323,6 +1397,12 @@ static HRESULT WINAPI d3d8_device_Clear(IDirect3DDevice8 *iface, DWORD rect_coun TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n", iface, rect_count, rects, flags, color, z, stencil); + if (rect_count && !rects) + { + WARN("count %u with NULL rects.\n", rect_count); + rect_count = 0; + } + wined3d_mutex_lock(); hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); wined3d_mutex_unlock(); @@ -1378,12 +1458,19 @@ static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface, static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); - /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */ + vp.x = viewport->X; + vp.y = viewport->Y; + vp.width = viewport->Width; + vp.height = viewport->Height; + vp.min_z = viewport->MinZ; + vp.max_z = viewport->MaxZ; + wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -1392,14 +1479,21 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPORT8 *viewport) { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); + struct wined3d_viewport wined3d_viewport; TRACE("iface %p, viewport %p.\n", iface, viewport); - /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */ wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); + viewport->X = wined3d_viewport.x; + viewport->Y = wined3d_viewport.y; + viewport->Width = wined3d_viewport.width; + viewport->Height = wined3d_viewport.height; + viewport->MinZ = wined3d_viewport.min_z; + viewport->MaxZ = wined3d_viewport.max_z; + return D3D_OK; } @@ -1590,7 +1684,7 @@ static HRESULT WINAPI d3d8_device_EndStateBlock(IDirect3DDevice8 *iface, DWORD * hr = wined3d_device_end_stateblock(device->wined3d_device, &stateblock); if (FAILED(hr)) { - WARN("IWineD3DDevice_EndStateBlock returned an error\n"); + WARN("Failed to end the state block, %#x.\n", hr); wined3d_mutex_unlock(); return hr; } @@ -1706,7 +1800,7 @@ static HRESULT WINAPI d3d8_device_CreateStateBlock(IDirect3DDevice8 *iface, if (FAILED(hr)) { wined3d_mutex_unlock(); - ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr); + ERR("Failed to create the state block, hr %#x\n", hr); return hr; } @@ -1805,39 +1899,43 @@ static HRESULT WINAPI d3d8_device_SetTexture(IDirect3DDevice8 *iface, DWORD stag static const struct tss_lookup { BOOL sampler_state; - enum wined3d_texture_stage_state state; + union + { + enum wined3d_texture_stage_state texture_state; + enum wined3d_sampler_state sampler_state; + } u; } tss_lookup[] = { - {FALSE, WINED3D_TSS_INVALID}, /* 0, unused */ - {FALSE, WINED3D_TSS_COLOR_OP}, /* 1, D3DTSS_COLOROP */ - {FALSE, WINED3D_TSS_COLOR_ARG1}, /* 2, D3DTSS_COLORARG1 */ - {FALSE, WINED3D_TSS_COLOR_ARG2}, /* 3, D3DTSS_COLORARG2 */ - {FALSE, WINED3D_TSS_ALPHA_OP}, /* 4, D3DTSS_ALPHAOP */ - {FALSE, WINED3D_TSS_ALPHA_ARG1}, /* 5, D3DTSS_ALPHAARG1 */ - {FALSE, WINED3D_TSS_ALPHA_ARG2}, /* 6, D3DTSS_ALPHAARG2 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT00}, /* 7, D3DTSS_BUMPENVMAT00 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT01}, /* 8, D3DTSS_BUMPENVMAT01 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT10}, /* 9, D3DTSS_BUMPENVMAT10 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT11}, /* 10, D3DTSS_BUMPENVMAT11 */ - {FALSE, WINED3D_TSS_TEXCOORD_INDEX}, /* 11, D3DTSS_TEXCOORDINDEX */ - {FALSE, WINED3D_TSS_INVALID}, /* 12, unused */ - {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 13, D3DTSS_ADDRESSU */ - {TRUE, WINED3D_SAMP_ADDRESS_V}, /* 14, D3DTSS_ADDRESSV */ - {TRUE, WINED3D_SAMP_BORDER_COLOR}, /* 15, D3DTSS_BORDERCOLOR */ - {TRUE, WINED3D_SAMP_MAG_FILTER}, /* 16, D3DTSS_MAGFILTER */ - {TRUE, WINED3D_SAMP_MIN_FILTER}, /* 17, D3DTSS_MINFILTER */ - {TRUE, WINED3D_SAMP_MIP_FILTER}, /* 18, D3DTSS_MIPFILTER */ - {TRUE, WINED3D_SAMP_MIPMAP_LOD_BIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */ - {TRUE, WINED3D_SAMP_MAX_MIP_LEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */ - {TRUE, WINED3D_SAMP_MAX_ANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */ - {FALSE, WINED3D_TSS_BUMPENV_LSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */ - {FALSE, WINED3D_TSS_BUMPENV_LOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */ - {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ - {TRUE, WINED3D_SAMP_ADDRESS_W}, /* 25, D3DTSS_ADDRESSW */ - {FALSE, WINED3D_TSS_COLOR_ARG0}, /* 26, D3DTSS_COLORARG0 */ - {FALSE, WINED3D_TSS_ALPHA_ARG0}, /* 27, D3DTSS_ALPHAARG0 */ - {FALSE, WINED3D_TSS_RESULT_ARG}, /* 28, D3DTSS_RESULTARG */ + {FALSE, {WINED3D_TSS_INVALID}}, /* 0, unused */ + {FALSE, {WINED3D_TSS_COLOR_OP}}, /* 1, D3DTSS_COLOROP */ + {FALSE, {WINED3D_TSS_COLOR_ARG1}}, /* 2, D3DTSS_COLORARG1 */ + {FALSE, {WINED3D_TSS_COLOR_ARG2}}, /* 3, D3DTSS_COLORARG2 */ + {FALSE, {WINED3D_TSS_ALPHA_OP}}, /* 4, D3DTSS_ALPHAOP */ + {FALSE, {WINED3D_TSS_ALPHA_ARG1}}, /* 5, D3DTSS_ALPHAARG1 */ + {FALSE, {WINED3D_TSS_ALPHA_ARG2}}, /* 6, D3DTSS_ALPHAARG2 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT00}}, /* 7, D3DTSS_BUMPENVMAT00 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT01}}, /* 8, D3DTSS_BUMPENVMAT01 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT10}}, /* 9, D3DTSS_BUMPENVMAT10 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT11}}, /* 10, D3DTSS_BUMPENVMAT11 */ + {FALSE, {WINED3D_TSS_TEXCOORD_INDEX}}, /* 11, D3DTSS_TEXCOORDINDEX */ + {FALSE, {WINED3D_TSS_INVALID}}, /* 12, unused */ + {TRUE, {WINED3D_SAMP_ADDRESS_U}}, /* 13, D3DTSS_ADDRESSU */ + {TRUE, {WINED3D_SAMP_ADDRESS_V}}, /* 14, D3DTSS_ADDRESSV */ + {TRUE, {WINED3D_SAMP_BORDER_COLOR}}, /* 15, D3DTSS_BORDERCOLOR */ + {TRUE, {WINED3D_SAMP_MAG_FILTER}}, /* 16, D3DTSS_MAGFILTER */ + {TRUE, {WINED3D_SAMP_MIN_FILTER}}, /* 17, D3DTSS_MINFILTER */ + {TRUE, {WINED3D_SAMP_MIP_FILTER}}, /* 18, D3DTSS_MIPFILTER */ + {TRUE, {WINED3D_SAMP_MIPMAP_LOD_BIAS}}, /* 19, D3DTSS_MIPMAPLODBIAS */ + {TRUE, {WINED3D_SAMP_MAX_MIP_LEVEL}}, /* 20, D3DTSS_MAXMIPLEVEL */ + {TRUE, {WINED3D_SAMP_MAX_ANISOTROPY}}, /* 21, D3DTSS_MAXANISOTROPY */ + {FALSE, {WINED3D_TSS_BUMPENV_LSCALE}}, /* 22, D3DTSS_BUMPENVLSCALE */ + {FALSE, {WINED3D_TSS_BUMPENV_LOFFSET}}, /* 23, D3DTSS_BUMPENVLOFFSET */ + {FALSE, {WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ + {TRUE, {WINED3D_SAMP_ADDRESS_W}}, /* 25, D3DTSS_ADDRESSW */ + {FALSE, {WINED3D_TSS_COLOR_ARG0}}, /* 26, D3DTSS_COLORARG0 */ + {FALSE, {WINED3D_TSS_ALPHA_ARG0}}, /* 27, D3DTSS_ALPHAARG0 */ + {FALSE, {WINED3D_TSS_RESULT_ARG}}, /* 28, D3DTSS_RESULTARG */ }; static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface, @@ -1858,9 +1956,9 @@ static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface, wined3d_mutex_lock(); if (l->sampler_state) - *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->state); + *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->u.sampler_state); else - *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->state); + *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->u.texture_state); wined3d_mutex_unlock(); return D3D_OK; @@ -1884,9 +1982,9 @@ static HRESULT WINAPI d3d8_device_SetTextureStageState(IDirect3DDevice8 *iface, wined3d_mutex_lock(); if (l->sampler_state) - wined3d_device_set_sampler_state(device->wined3d_device, stage, l->state, value); + wined3d_device_set_sampler_state(device->wined3d_device, stage, l->u.sampler_state, value); else - wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->state, value); + wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->u.texture_state, value); wined3d_mutex_unlock(); return D3D_OK; @@ -1957,7 +2055,7 @@ static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface, iface, primitive_type, start_vertex, primitive_count); wined3d_mutex_lock(); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count_from_primitive_count(primitive_type, primitive_count)); wined3d_mutex_unlock(); @@ -1976,7 +2074,7 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface, iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count); wined3d_mutex_lock(); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, vertex_count_from_primitive_count(primitive_type, primitive_count)); wined3d_mutex_unlock(); @@ -2021,9 +2119,11 @@ static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface, struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); HRESULT hr; UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; UINT size = vtx_count * stride; + struct wined3d_resource *vb; UINT vb_pos, align; - BYTE *buffer_data; TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", iface, primitive_type, primitive_count, data, stride); @@ -2047,19 +2147,21 @@ static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface, else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &buffer_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, data, size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, data, size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); if (FAILED(hr)) goto done; - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); @@ -2103,19 +2205,18 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface UINT primitive_count, const void *index_data, D3DFORMAT index_format, const void *vertex_data, UINT vertex_stride) { - struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); - HRESULT hr; - BYTE *buffer_data; - UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4; - UINT idx_size = idx_count * idx_fmt_size; - UINT ib_pos; - UINT vtx_size = vertex_count * vertex_stride; - UINT vb_pos, align; + UINT idx_size = idx_count * idx_fmt_size; + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *ib, *vb; + UINT vb_pos, ib_pos, align; + HRESULT hr; - TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u,\n" + TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u, " "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n", iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, index_data, index_format, vertex_data, vertex_stride); @@ -2140,12 +2241,14 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &buffer_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + vtx_size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, vertex_data, vtx_size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + vtx_size; hr = d3d8_device_prepare_index_buffer(device, idx_size); @@ -2160,12 +2263,14 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface else ib_pos += align; - hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &buffer_data, - ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = ib_pos; + wined3d_box.right = ib_pos + idx_size; + ib = wined3d_buffer_get_resource(device->index_buffer); + if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, + ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, index_data, idx_size); - wined3d_buffer_unmap(device->index_buffer); + memcpy(wined3d_map_desc.data, index_data, idx_size); + wined3d_resource_unmap(ib, 0); device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride); @@ -2173,14 +2278,14 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface goto done; wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, - wined3dformat_from_d3dformat(index_format)); - wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride); + wined3dformat_from_d3dformat(index_format), 0); + wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); - wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN); + wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, 0); done: @@ -2429,7 +2534,7 @@ static HRESULT WINAPI d3d8_device_SetVertexShaderConstant(IDirect3DDevice8 *ifac } wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, data, count); + hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -2452,7 +2557,7 @@ static HRESULT WINAPI d3d8_device_GetVertexShaderConstant(IDirect3DDevice8 *ifac } wined3d_mutex_lock(); - hr = wined3d_device_get_vs_consts_f(device->wined3d_device, start_register, data, count); + hr = wined3d_device_get_vs_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -2545,8 +2650,7 @@ static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface, wined3d_mutex_lock(); wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); wined3d_device_set_index_buffer(device->wined3d_device, - ib ? ib->wined3d_buffer : NULL, - ib ? ib->format : WINED3DFMT_UNKNOWN); + ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); wined3d_mutex_unlock(); return D3D_OK; @@ -2568,7 +2672,7 @@ static HRESULT WINAPI d3d8_device_GetIndices(IDirect3DDevice8 *iface, /* The case from UINT to INT is safe because d3d8 will never set negative values */ wined3d_mutex_lock(); *base_vertex_index = wined3d_device_get_base_vertex_index(device->wined3d_device); - if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format))) + if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, NULL))) { buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); *buffer = &buffer_impl->IDirect3DIndexBuffer8_iface; @@ -2725,7 +2829,7 @@ static HRESULT WINAPI d3d8_device_SetPixelShaderConstant(IDirect3DDevice8 *iface iface, start_register, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, data, count); + hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -2741,7 +2845,7 @@ static HRESULT WINAPI d3d8_device_GetPixelShaderConstant(IDirect3DDevice8 *iface iface, start_register, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_ps_consts_f(device->wined3d_device, start_register, data, count); + hr = wined3d_device_get_ps_consts_f(device->wined3d_device, start_register, count, data); wined3d_mutex_unlock(); return hr; @@ -3013,17 +3117,19 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent * } static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture) + void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, + struct wined3d_texture **texture) { struct d3d8_device *device = device_from_device_parent(device_parent); struct d3d8_surface *d3d_surface; HRESULT hr; - TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n", - device_parent, container_parent, desc, texture); + TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", + device_parent, container_parent, desc, texture_flags, texture); - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, - NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, + texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, + &d3d8_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/reactos/dll/directx/wine/d3d8/directx.c b/reactos/dll/directx/wine/d3d8/directx.c index 081befe823d..35bf76a28e7 100644 --- a/reactos/dll/directx/wine/d3d8/directx.c +++ b/reactos/dll/directx/wine/d3d8/directx.c @@ -231,27 +231,20 @@ static HRESULT WINAPI d3d8_CheckDeviceFormat(IDirect3D8 *iface, UINT adapter, D3 usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { - case D3DRTYPE_SURFACE: - wined3d_rtype = WINED3D_RTYPE_SURFACE; - break; - - case D3DRTYPE_VOLUME: - wined3d_rtype = WINED3D_RTYPE_VOLUME; - break; - + case D3DRTYPE_CUBETEXTURE: + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; case D3DRTYPE_TEXTURE: + usage |= WINED3DUSAGE_TEXTURE; + case D3DRTYPE_SURFACE: wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; break; case D3DRTYPE_VOLUMETEXTURE: + case D3DRTYPE_VOLUME: + usage |= WINED3DUSAGE_TEXTURE; wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; break; - case D3DRTYPE_CUBETEXTURE: - wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; - usage |= WINED3DUSAGE_LEGACY_CUBEMAP; - break; - case D3DRTYPE_VERTEXBUFFER: case D3DRTYPE_INDEXBUFFER: wined3d_rtype = WINED3D_RTYPE_BUFFER; @@ -309,26 +302,10 @@ static HRESULT WINAPI d3d8_CheckDepthStencilMatch(IDirect3D8 *iface, UINT adapte return hr; } -void fixup_caps(WINED3DCAPS *caps) -{ - /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */ - if (caps->PixelShaderVersion) - caps->PixelShaderVersion = D3DPS_VERSION(1,4); - else - caps->PixelShaderVersion = D3DPS_VERSION(0,0); - if (caps->VertexShaderVersion) - caps->VertexShaderVersion = D3DVS_VERSION(1,1); - else - caps->VertexShaderVersion = D3DVS_VERSION(0,0); - caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); - - caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; -} - static HRESULT WINAPI d3d8_GetDeviceCaps(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS8 *caps) { struct d3d8 *d3d8 = impl_from_IDirect3D8(iface); - WINED3DCAPS *wined3d_caps; + WINED3DCAPS wined3d_caps; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps); @@ -336,16 +313,11 @@ static HRESULT WINAPI d3d8_GetDeviceCaps(IDirect3D8 *iface, UINT adapter, D3DDEV if (!caps) return D3DERR_INVALIDCALL; - if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps)))) - return D3DERR_INVALIDCALL; - wined3d_mutex_lock(); - hr = wined3d_get_device_caps(d3d8->wined3d, adapter, device_type, wined3d_caps); + hr = wined3d_get_device_caps(d3d8->wined3d, adapter, device_type, &wined3d_caps); wined3d_mutex_unlock(); - fixup_caps(wined3d_caps); - WINECAPSTOD3D8CAPS(caps, wined3d_caps) - HeapFree(GetProcessHeap(), 0, wined3d_caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps); return hr; } @@ -425,7 +397,9 @@ static const struct IDirect3D8Vtbl d3d8_vtbl = BOOL d3d8_init(struct d3d8 *d3d8) { DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING - | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER; + | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER + | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART + | WINED3D_LEGACY_CUBEMAP_FILTERING; d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; d3d8->refcount = 1; diff --git a/reactos/dll/directx/wine/d3d8/shader.c b/reactos/dll/directx/wine/d3d8/shader.c index 1b568999d43..d0361a9e837 100644 --- a/reactos/dll/directx/wine/d3d8/shader.c +++ b/reactos/dll/directx/wine/d3d8/shader.c @@ -114,8 +114,11 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d FIXME("Usage %#x not implemented.\n", usage); desc.byte_code = byte_code; - desc.input_signature = NULL; - desc.output_signature = NULL; + desc.byte_code_size = ~(size_t)0; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; + desc.input_signature.element_count = 0; + desc.output_signature.element_count = 0; + desc.patch_constant_signature.element_count = 0; desc.max_version = 1; wined3d_mutex_lock(); @@ -163,8 +166,11 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev shader->handle = shader_handle; desc.byte_code = byte_code; - desc.input_signature = NULL; - desc.output_signature = NULL; + desc.byte_code_size = ~(size_t)0; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; + desc.input_signature.element_count = 0; + desc.output_signature.element_count = 0; + desc.patch_constant_signature.element_count = 0; desc.max_version = 1; wined3d_mutex_lock(); diff --git a/reactos/dll/directx/wine/d3d8/surface.c b/reactos/dll/directx/wine/d3d8/surface.c index b354850c18e..545361644b8 100644 --- a/reactos/dll/directx/wine/d3d8/surface.c +++ b/reactos/dll/directx/wine/d3d8/surface.c @@ -87,6 +87,12 @@ static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface) return IDirect3DBaseTexture8_Release(&surface->texture->IDirect3DBaseTexture8_iface); } + if (!surface->resource.refcount) + { + WARN("Surface does not have any references.\n"); + return 0; + } + refcount = InterlockedDecrement(&surface->resource.refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); @@ -172,18 +178,16 @@ static HRESULT WINAPI d3d8_surface_GetContainer(IDirect3DSurface8 *iface, REFIID static HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_DESC *desc) { struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface); - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *sub_resource; + struct wined3d_sub_resource_desc wined3d_desc; TRACE("iface %p, desc %p.\n", iface, desc); wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &wined3d_desc); wined3d_mutex_unlock(); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Size = wined3d_desc.size; @@ -233,15 +237,10 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, locked_rect->pBits = NULL; return D3DERR_INVALIDCALL; } - box.left = rect->left; - box.top = rect->top; - box.right = rect->right; - box.bottom = rect->bottom; - box.front = 0; - box.back = 1; + wined3d_box_set(&box, rect->left, rect->top, rect->right, rect->bottom, 0, 1); } - hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, + hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags); wined3d_mutex_unlock(); @@ -267,14 +266,19 @@ static HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); wined3d_mutex_unlock(); - switch(hr) + if (hr == WINEDDERR_NOTLOCKED) { - case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL; - default: return hr; + D3DRESOURCETYPE type; + if (surface->texture) + type = IDirect3DBaseTexture8_GetType(&surface->texture->IDirect3DBaseTexture8_iface); + else + type = D3DRTYPE_SURFACE; + hr = type == D3DRTYPE_TEXTURE ? D3D_OK : D3DERR_INVALIDCALL; } + return hr; } static const IDirect3DSurface8Vtbl d3d8_surface_vtbl = @@ -352,10 +356,22 @@ static const struct wined3d_parent_ops d3d8_view_wined3d_parent_ops = view_wined3d_object_destroyed, }; -struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_surface *surface) +struct d3d8_device *d3d8_surface_get_device(const struct d3d8_surface *surface) +{ + IDirect3DDevice8 *device; + device = surface->texture ? surface->texture->parent_device : surface->parent_device; + return impl_from_IDirect3DDevice8(device); +} + +struct wined3d_rendertarget_view *d3d8_surface_acquire_rendertarget_view(struct d3d8_surface *surface) { HRESULT hr; + /* The surface reference count can be equal to 0 when this function is + * called. In order to properly manage the render target view reference + * count, we temporarily increment the surface reference count. */ + d3d8_surface_AddRef(&surface->IDirect3DSurface8_iface); + if (surface->wined3d_rtv) return surface->wined3d_rtv; @@ -363,6 +379,7 @@ struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8 surface->sub_resource_idx, surface, &d3d8_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); + d3d8_surface_Release(&surface->IDirect3DSurface8_iface); return NULL; } @@ -372,6 +389,13 @@ struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8 return surface->wined3d_rtv; } +void d3d8_surface_release_rendertarget_view(struct d3d8_surface *surface, + struct wined3d_rendertarget_view *rtv) +{ + if (rtv) + d3d8_surface_Release(&surface->IDirect3DSurface8_iface); +} + struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) { if (!iface) diff --git a/reactos/dll/directx/wine/d3d8/swapchain.c b/reactos/dll/directx/wine/d3d8/swapchain.c index 3812e6bf2a0..d82a8ed657a 100644 --- a/reactos/dll/directx/wine/d3d8/swapchain.c +++ b/reactos/dll/directx/wine/d3d8/swapchain.c @@ -97,9 +97,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai if (device->device_state != D3D8_DEVICE_STATE_OK) return D3DERR_DEVICELOST; + if (dirty_region) + FIXME("Ignoring dirty_region %p.\n", dirty_region); + wined3d_mutex_lock(); - hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect, - dst_rect, dst_window_override, dirty_region, 0); + hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, 0); wined3d_mutex_unlock(); return hr; diff --git a/reactos/dll/directx/wine/d3d8/texture.c b/reactos/dll/directx/wine/d3d8/texture.c index b0621ce9ac1..c0fa7469ae6 100644 --- a/reactos/dll/directx/wine/d3d8/texture.c +++ b/reactos/dll/directx/wine/d3d8/texture.c @@ -20,17 +20,17 @@ static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface) { - return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface) { - return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) { - return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out) @@ -184,7 +184,7 @@ static void WINAPI d3d8_texture_2d_PreLoad(IDirect3DTexture8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -240,21 +240,16 @@ static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface) static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UINT level, D3DSURFACE_DESC *desc) { struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Size = wined3d_desc.size; @@ -342,12 +337,7 @@ static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, con { struct wined3d_box dirty_region; - dirty_region.left = dirty_rect->left; - dirty_region.top = dirty_rect->top; - dirty_region.right = dirty_rect->right; - dirty_region.bottom = dirty_rect->bottom; - dirty_region.front = 0; - dirty_region.back = 1; + wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region); } wined3d_mutex_unlock(); @@ -535,7 +525,7 @@ static void WINAPI d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -591,8 +581,8 @@ static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *iface, UINT level, D3DSURFACE_DESC *desc) { struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); @@ -603,15 +593,10 @@ static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *ifac return D3DERR_INVALIDCALL; } - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Size = wined3d_desc.size; @@ -716,12 +701,7 @@ static HRESULT WINAPI d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8 *ifac { struct wined3d_box dirty_region; - dirty_region.left = dirty_rect->left; - dirty_region.top = dirty_rect->top; - dirty_region.right = dirty_rect->right; - dirty_region.bottom = dirty_rect->bottom; - dirty_region.front = 0; - dirty_region.back = 1; + wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region); } wined3d_mutex_unlock(); @@ -896,7 +876,7 @@ static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -952,21 +932,16 @@ static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc) { struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_VOLUME; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Size = wined3d_desc.size; @@ -983,19 +958,17 @@ static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *if UINT level, IDirect3DVolume8 **volume) { struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; struct d3d8_volume *volume_impl; TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } - volume_impl = wined3d_resource_get_parent(sub_resource); *volume = &volume_impl->IDirect3DVolume8_iface; IDirect3DVolume8_AddRef(*volume); wined3d_mutex_unlock(); @@ -1145,7 +1118,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, levels = wined3d_log2i(max(width, height)) + 1; wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1190,7 +1163,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic levels = wined3d_log2i(edge_length) + 1; wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1231,7 +1204,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev levels = wined3d_log2i(max(max(width, height), depth)) + 1; wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, + hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0, NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) diff --git a/reactos/dll/directx/wine/d3d8/vertexdeclaration.c b/reactos/dll/directx/wine/d3d8/vertexdeclaration.c index 1818f6d1dd8..e01230e5ae2 100644 --- a/reactos/dll/directx/wine/d3d8/vertexdeclaration.c +++ b/reactos/dll/directx/wine/d3d8/vertexdeclaration.c @@ -217,8 +217,8 @@ static const enum wined3d_format_id wined3d_format_lookup[] = /*WINED3DDECLTYPE_SHORT4N*/ WINED3DFMT_R16G16B16A16_SNORM, /*WINED3DDECLTYPE_USHORT2N*/ WINED3DFMT_R16G16_UNORM, /*WINED3DDECLTYPE_USHORT4N*/ WINED3DFMT_R16G16B16A16_UNORM, - /*WINED3DDECLTYPE_UDEC3*/ WINED3DFMT_R10G10B10A2_UINT, - /*WINED3DDECLTYPE_DEC3N*/ WINED3DFMT_R10G10B10A2_SNORM, + /*WINED3DDECLTYPE_UDEC3*/ WINED3DFMT_R10G10B10X2_UINT, + /*WINED3DDECLTYPE_DEC3N*/ WINED3DFMT_R10G10B10X2_SNORM, /*WINED3DDECLTYPE_FLOAT16_2*/ WINED3DFMT_R16G16_FLOAT, /*WINED3DDECLTYPE_FLOAT16_4*/ WINED3DFMT_R16G16B16A16_FLOAT, }; diff --git a/reactos/dll/directx/wine/d3d8/volume.c b/reactos/dll/directx/wine/d3d8/volume.c index 302ee0d48ba..0e1e904e2f5 100644 --- a/reactos/dll/directx/wine/d3d8/volume.c +++ b/reactos/dll/directx/wine/d3d8/volume.c @@ -112,18 +112,16 @@ static HRESULT WINAPI d3d8_volume_GetContainer(IDirect3DVolume8 *iface, REFIID r static HRESULT WINAPI d3d8_volume_GetDesc(IDirect3DVolume8 *iface, D3DVOLUME_DESC *desc) { struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface); - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *sub_resource; + struct wined3d_sub_resource_desc wined3d_desc; TRACE("iface %p, desc %p.\n", iface, desc); wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(volume->wined3d_texture, volume->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(volume->wined3d_texture, volume->sub_resource_idx, &wined3d_desc); wined3d_mutex_unlock(); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_VOLUME; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Size = wined3d_desc.size; @@ -145,8 +143,9 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface, iface, locked_box, box, flags); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); + if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), + volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags))) + map_desc.data = NULL; wined3d_mutex_unlock(); locked_box->RowPitch = map_desc.row_pitch; @@ -164,9 +163,11 @@ static HRESULT WINAPI d3d8_volume_UnlockBox(IDirect3DVolume8 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); wined3d_mutex_unlock(); + if (hr == WINEDDERR_NOTLOCKED) + return D3DERR_INVALIDCALL; return hr; } diff --git a/reactos/dll/directx/wine/d3d9/CMakeLists.txt b/reactos/dll/directx/wine/d3d9/CMakeLists.txt index 95550c404f8..9dd8b4aa6a9 100644 --- a/reactos/dll/directx/wine/d3d9/CMakeLists.txt +++ b/reactos/dll/directx/wine/d3d9/CMakeLists.txt @@ -30,6 +30,6 @@ add_library(d3d9 SHARED set_module_type(d3d9 win32dll UNICODE) target_link_libraries(d3d9 wine) -add_importlibs(d3d9 d3dwine msvcrt kernel32 ntdll) +add_importlibs(d3d9 d3dwine user32 msvcrt kernel32 ntdll) add_pch(d3d9 d3d9_private.h SOURCE) add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/directx/wine/d3d9/buffer.c b/reactos/dll/directx/wine/d3d9/buffer.c index 9101fd10cc4..462ef3bb974 100644 --- a/reactos/dll/directx/wine/d3d9/buffer.c +++ b/reactos/dll/directx/wine/d3d9/buffer.c @@ -165,7 +165,7 @@ static void WINAPI d3d9_vertexbuffer_PreLoad(IDirect3DVertexBuffer9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_preload(buffer->wined3d_buffer); + wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer)); wined3d_mutex_unlock(); } @@ -180,14 +180,20 @@ static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT void **data, DWORD flags) { struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; HRESULT hr; TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n", iface, offset, size, data, flags); + wined3d_box.left = offset; + wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, (BYTE **)data, flags); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), + 0, &wined3d_map_desc, &wined3d_box, flags); wined3d_mutex_unlock(); + *data = wined3d_map_desc.data; return hr; } @@ -199,7 +205,7 @@ static HRESULT WINAPI d3d9_vertexbuffer_Unlock(IDirect3DVertexBuffer9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_unmap(buffer->wined3d_buffer); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); wined3d_mutex_unlock(); return D3D_OK; @@ -441,7 +447,7 @@ static void WINAPI d3d9_indexbuffer_PreLoad(IDirect3DIndexBuffer9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_preload(buffer->wined3d_buffer); + wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer)); wined3d_mutex_unlock(); } @@ -456,14 +462,20 @@ static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface, UINT offset, UINT size, void **data, DWORD flags) { struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; HRESULT hr; TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n", iface, offset, size, data, flags); + wined3d_box.left = offset; + wined3d_box.right = offset + size; wined3d_mutex_lock(); - hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, (BYTE **)data, flags); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), + 0, &wined3d_map_desc, &wined3d_box, flags); wined3d_mutex_unlock(); + *data = wined3d_map_desc.data; return hr; } @@ -475,7 +487,7 @@ static HRESULT WINAPI d3d9_indexbuffer_Unlock(IDirect3DIndexBuffer9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_unmap(buffer->wined3d_buffer); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); wined3d_mutex_unlock(); return D3D_OK; diff --git a/reactos/dll/directx/wine/d3d9/d3d9_private.h b/reactos/dll/directx/wine/d3d9/d3d9_private.h index a4df8287f93..2649a5bc965 100644 --- a/reactos/dll/directx/wine/d3d9/d3d9_private.h +++ b/reactos/dll/directx/wine/d3d9/d3d9_private.h @@ -37,6 +37,7 @@ #define COBJMACROS #include #include +#include #include #include @@ -45,88 +46,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d9); #include #include -extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN; +#define D3DPRESENTFLAGS_MASK 0x00000fffu + +extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN; + +HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN; D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; +BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN; void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN; - -#define WINECAPSTOD3D9CAPS(_pD3D9Caps, _pWineCaps) \ - _pD3D9Caps->DeviceType = (D3DDEVTYPE) _pWineCaps->DeviceType; \ - _pD3D9Caps->AdapterOrdinal = _pWineCaps->AdapterOrdinal; \ - _pD3D9Caps->Caps = _pWineCaps->Caps; \ - _pD3D9Caps->Caps2 = _pWineCaps->Caps2; \ - _pD3D9Caps->Caps3 = _pWineCaps->Caps3; \ - _pD3D9Caps->PresentationIntervals = _pWineCaps->PresentationIntervals; \ - _pD3D9Caps->CursorCaps = _pWineCaps->CursorCaps; \ - _pD3D9Caps->DevCaps = _pWineCaps->DevCaps; \ - _pD3D9Caps->PrimitiveMiscCaps = _pWineCaps->PrimitiveMiscCaps; \ - _pD3D9Caps->RasterCaps = _pWineCaps->RasterCaps; \ - _pD3D9Caps->ZCmpCaps = _pWineCaps->ZCmpCaps; \ - _pD3D9Caps->SrcBlendCaps = _pWineCaps->SrcBlendCaps; \ - _pD3D9Caps->DestBlendCaps = _pWineCaps->DestBlendCaps; \ - _pD3D9Caps->AlphaCmpCaps = _pWineCaps->AlphaCmpCaps; \ - _pD3D9Caps->ShadeCaps = _pWineCaps->ShadeCaps; \ - _pD3D9Caps->TextureCaps = _pWineCaps->TextureCaps; \ - _pD3D9Caps->TextureFilterCaps = _pWineCaps->TextureFilterCaps; \ - _pD3D9Caps->CubeTextureFilterCaps = _pWineCaps->CubeTextureFilterCaps; \ - _pD3D9Caps->VolumeTextureFilterCaps = _pWineCaps->VolumeTextureFilterCaps; \ - _pD3D9Caps->TextureAddressCaps = _pWineCaps->TextureAddressCaps; \ - _pD3D9Caps->VolumeTextureAddressCaps = _pWineCaps->VolumeTextureAddressCaps; \ - _pD3D9Caps->LineCaps = _pWineCaps->LineCaps; \ - _pD3D9Caps->MaxTextureWidth = _pWineCaps->MaxTextureWidth; \ - _pD3D9Caps->MaxTextureHeight = _pWineCaps->MaxTextureHeight; \ - _pD3D9Caps->MaxVolumeExtent = _pWineCaps->MaxVolumeExtent; \ - _pD3D9Caps->MaxTextureRepeat = _pWineCaps->MaxTextureRepeat; \ - _pD3D9Caps->MaxTextureAspectRatio = _pWineCaps->MaxTextureAspectRatio; \ - _pD3D9Caps->MaxAnisotropy = _pWineCaps->MaxAnisotropy; \ - _pD3D9Caps->MaxVertexW = _pWineCaps->MaxVertexW; \ - _pD3D9Caps->GuardBandLeft = _pWineCaps->GuardBandLeft; \ - _pD3D9Caps->GuardBandTop = _pWineCaps->GuardBandTop; \ - _pD3D9Caps->GuardBandRight = _pWineCaps->GuardBandRight; \ - _pD3D9Caps->GuardBandBottom = _pWineCaps->GuardBandBottom; \ - _pD3D9Caps->ExtentsAdjust = _pWineCaps->ExtentsAdjust; \ - _pD3D9Caps->StencilCaps = _pWineCaps->StencilCaps; \ - _pD3D9Caps->FVFCaps = _pWineCaps->FVFCaps; \ - _pD3D9Caps->TextureOpCaps = _pWineCaps->TextureOpCaps; \ - _pD3D9Caps->MaxTextureBlendStages = _pWineCaps->MaxTextureBlendStages; \ - _pD3D9Caps->MaxSimultaneousTextures = _pWineCaps->MaxSimultaneousTextures; \ - _pD3D9Caps->VertexProcessingCaps = _pWineCaps->VertexProcessingCaps; \ - _pD3D9Caps->MaxActiveLights = _pWineCaps->MaxActiveLights; \ - _pD3D9Caps->MaxUserClipPlanes = _pWineCaps->MaxUserClipPlanes; \ - _pD3D9Caps->MaxVertexBlendMatrices = _pWineCaps->MaxVertexBlendMatrices; \ - _pD3D9Caps->MaxVertexBlendMatrixIndex = _pWineCaps->MaxVertexBlendMatrixIndex; \ - _pD3D9Caps->MaxPointSize = _pWineCaps->MaxPointSize; \ - _pD3D9Caps->MaxPrimitiveCount = _pWineCaps->MaxPrimitiveCount; \ - _pD3D9Caps->MaxVertexIndex = _pWineCaps->MaxVertexIndex; \ - _pD3D9Caps->MaxStreams = _pWineCaps->MaxStreams; \ - _pD3D9Caps->MaxStreamStride = _pWineCaps->MaxStreamStride; \ - _pD3D9Caps->VertexShaderVersion = _pWineCaps->VertexShaderVersion; \ - _pD3D9Caps->MaxVertexShaderConst = _pWineCaps->MaxVertexShaderConst; \ - _pD3D9Caps->PixelShaderVersion = _pWineCaps->PixelShaderVersion; \ - _pD3D9Caps->PixelShader1xMaxValue = _pWineCaps->PixelShader1xMaxValue; \ - _pD3D9Caps->DevCaps2 = _pWineCaps->DevCaps2; \ - _pD3D9Caps->MaxNpatchTessellationLevel = _pWineCaps->MaxNpatchTessellationLevel; \ - _pD3D9Caps->MasterAdapterOrdinal = _pWineCaps->MasterAdapterOrdinal; \ - _pD3D9Caps->AdapterOrdinalInGroup = _pWineCaps->AdapterOrdinalInGroup; \ - _pD3D9Caps->NumberOfAdaptersInGroup = _pWineCaps->NumberOfAdaptersInGroup; \ - _pD3D9Caps->DeclTypes = _pWineCaps->DeclTypes; \ - _pD3D9Caps->NumSimultaneousRTs = _pWineCaps->NumSimultaneousRTs; \ - _pD3D9Caps->StretchRectFilterCaps = _pWineCaps->StretchRectFilterCaps; \ - _pD3D9Caps->VS20Caps.Caps = _pWineCaps->VS20Caps.caps; \ - _pD3D9Caps->VS20Caps.DynamicFlowControlDepth = _pWineCaps->VS20Caps.dynamic_flow_control_depth; \ - _pD3D9Caps->VS20Caps.NumTemps = _pWineCaps->VS20Caps.temp_count; \ - _pD3D9Caps->VS20Caps.StaticFlowControlDepth = _pWineCaps->VS20Caps.static_flow_control_depth; \ - _pD3D9Caps->PS20Caps.Caps = _pWineCaps->PS20Caps.caps; \ - _pD3D9Caps->PS20Caps.DynamicFlowControlDepth = _pWineCaps->PS20Caps.dynamic_flow_control_depth; \ - _pD3D9Caps->PS20Caps.NumTemps = _pWineCaps->PS20Caps.temp_count; \ - _pD3D9Caps->PS20Caps.StaticFlowControlDepth = _pWineCaps->PS20Caps.static_flow_control_depth; \ - _pD3D9Caps->PS20Caps.NumInstructionSlots = _pWineCaps->PS20Caps.instruction_slot_count; \ - _pD3D9Caps->VertexTextureFilterCaps = _pWineCaps->VertexTextureFilterCaps; \ - _pD3D9Caps->MaxVShaderInstructionsExecuted = _pWineCaps->MaxVShaderInstructionsExecuted; \ - _pD3D9Caps->MaxPShaderInstructionsExecuted = _pWineCaps->MaxPShaderInstructionsExecuted; \ - _pD3D9Caps->MaxVertexShader30InstructionSlots = _pWineCaps->MaxVertexShader30InstructionSlots; \ - _pD3D9Caps->MaxPixelShader30InstructionSlots = _pWineCaps->MaxPixelShader30InstructionSlots; +void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN; struct d3d9 { @@ -137,7 +67,6 @@ struct d3d9 }; BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) DECLSPEC_HIDDEN; -void filter_caps(D3DCAPS9* pCaps) DECLSPEC_HIDDEN; struct fvf_declaration { @@ -173,6 +102,7 @@ struct d3d9_device LONG device_state; BOOL in_destruction; BOOL in_scene; + BOOL has_vertex_declaration; UINT implicit_swapchain_count; struct d3d9_swapchain **implicit_swapchains; @@ -230,10 +160,12 @@ struct d3d9_surface IDirect3DDevice9Ex *parent_device; IUnknown *container; struct d3d9_texture *texture; - BOOL getdc_supported; }; -struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; +struct wined3d_rendertarget_view *d3d9_surface_acquire_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; +struct d3d9_device *d3d9_surface_get_device(const struct d3d9_surface *surface) DECLSPEC_HIDDEN; +void d3d9_surface_release_rendertarget_view(struct d3d9_surface *surface, + struct wined3d_rendertarget_view *rtv) DECLSPEC_HIDDEN; void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN; @@ -341,6 +273,7 @@ struct d3d9_query LONG refcount; struct wined3d_query *wined3d_query; IDirect3DDevice9Ex *parent_device; + DWORD data_size; }; HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUERYTYPE type) DECLSPEC_HIDDEN; diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index 1d6e4b1d244..459a24ddf0e 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -24,7 +24,7 @@ static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {} -static const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops = +const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops = { d3d9_null_wined3d_object_destroyed, }; @@ -77,7 +77,6 @@ D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) case WINED3DFMT_L16_UNORM: return D3DFMT_L16; case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE; case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8; - case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA; case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16; case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32; case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16; @@ -142,7 +141,6 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) case D3DFMT_L16: return WINED3DFMT_L16_UNORM; case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT; case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT; - case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA; case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT; case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT; case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM; @@ -154,14 +152,14 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT; case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx; default: - FIXME("Unhandled D3DFORMAT %#x\n", format); + FIXME("Unhandled D3DFORMAT %#x.\n", format); return WINED3DFMT_UNKNOWN; } } static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) { - switch(primitive_type) + switch (primitive_type) { case D3DPT_POINTLIST: return primitive_count; @@ -180,7 +178,7 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U return primitive_count + 2; default: - FIXME("Unhandled primitive type %#x\n", primitive_type); + FIXME("Unhandled primitive type %#x.\n", primitive_type); return 0; } } @@ -200,7 +198,7 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil; present_parameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); - present_parameters->Flags = swapchain_desc->flags; + present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; present_parameters->PresentationInterval = swapchain_desc->swap_interval; } @@ -236,14 +234,182 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil; swapchain_desc->auto_depth_stencil_format = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat); - swapchain_desc->flags = present_parameters->Flags; + swapchain_desc->flags + = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; + if (is_gdi_compat_wined3dformat(swapchain_desc->backbuffer_format)) + swapchain_desc->flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE; swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; swapchain_desc->swap_interval = present_parameters->PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; + if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) + FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK); + return TRUE; } +void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) +{ + static const DWORD ps_minor_version[] = {0, 4, 0, 0}; + static const DWORD vs_minor_version[] = {0, 1, 0, 0}; + static const DWORD texture_filter_caps = + D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | + D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | D3DPTFILTERCAPS_MINFGAUSSIANQUAD| + D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | + D3DPTFILTERCAPS_MAGFLINEAR |D3DPTFILTERCAPS_MAGFANISOTROPIC|D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD| + D3DPTFILTERCAPS_MAGFGAUSSIANQUAD; + + caps->DeviceType = (D3DDEVTYPE)wined3d_caps->DeviceType; + caps->AdapterOrdinal = wined3d_caps->AdapterOrdinal; + caps->Caps = wined3d_caps->Caps; + caps->Caps2 = wined3d_caps->Caps2; + caps->Caps3 = wined3d_caps->Caps3; + caps->PresentationIntervals = wined3d_caps->PresentationIntervals; + caps->CursorCaps = wined3d_caps->CursorCaps; + caps->DevCaps = wined3d_caps->DevCaps; + caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; + caps->RasterCaps = wined3d_caps->RasterCaps; + caps->ZCmpCaps = wined3d_caps->ZCmpCaps; + caps->SrcBlendCaps = wined3d_caps->SrcBlendCaps; + caps->DestBlendCaps = wined3d_caps->DestBlendCaps; + caps->AlphaCmpCaps = wined3d_caps->AlphaCmpCaps; + caps->ShadeCaps = wined3d_caps->ShadeCaps; + caps->TextureCaps = wined3d_caps->TextureCaps; + caps->TextureFilterCaps = wined3d_caps->TextureFilterCaps; + caps->CubeTextureFilterCaps = wined3d_caps->CubeTextureFilterCaps; + caps->VolumeTextureFilterCaps = wined3d_caps->VolumeTextureFilterCaps; + caps->TextureAddressCaps = wined3d_caps->TextureAddressCaps; + caps->VolumeTextureAddressCaps = wined3d_caps->VolumeTextureAddressCaps; + caps->LineCaps = wined3d_caps->LineCaps; + caps->MaxTextureWidth = wined3d_caps->MaxTextureWidth; + caps->MaxTextureHeight = wined3d_caps->MaxTextureHeight; + caps->MaxVolumeExtent = wined3d_caps->MaxVolumeExtent; + caps->MaxTextureRepeat = wined3d_caps->MaxTextureRepeat; + caps->MaxTextureAspectRatio = wined3d_caps->MaxTextureAspectRatio; + caps->MaxAnisotropy = wined3d_caps->MaxAnisotropy; + caps->MaxVertexW = wined3d_caps->MaxVertexW; + caps->GuardBandLeft = wined3d_caps->GuardBandLeft; + caps->GuardBandTop = wined3d_caps->GuardBandTop; + caps->GuardBandRight = wined3d_caps->GuardBandRight; + caps->GuardBandBottom = wined3d_caps->GuardBandBottom; + caps->ExtentsAdjust = wined3d_caps->ExtentsAdjust; + caps->StencilCaps = wined3d_caps->StencilCaps; + caps->FVFCaps = wined3d_caps->FVFCaps; + caps->TextureOpCaps = wined3d_caps->TextureOpCaps; + caps->MaxTextureBlendStages = wined3d_caps->MaxTextureBlendStages; + caps->MaxSimultaneousTextures = wined3d_caps->MaxSimultaneousTextures; + caps->VertexProcessingCaps = wined3d_caps->VertexProcessingCaps; + caps->MaxActiveLights = wined3d_caps->MaxActiveLights; + caps->MaxUserClipPlanes = wined3d_caps->MaxUserClipPlanes; + caps->MaxVertexBlendMatrices = wined3d_caps->MaxVertexBlendMatrices; + caps->MaxVertexBlendMatrixIndex = wined3d_caps->MaxVertexBlendMatrixIndex; + caps->MaxPointSize = wined3d_caps->MaxPointSize; + caps->MaxPrimitiveCount = wined3d_caps->MaxPrimitiveCount; + caps->MaxVertexIndex = wined3d_caps->MaxVertexIndex; + caps->MaxStreams = wined3d_caps->MaxStreams; + caps->MaxStreamStride = wined3d_caps->MaxStreamStride; + caps->VertexShaderVersion = wined3d_caps->VertexShaderVersion; + caps->MaxVertexShaderConst = wined3d_caps->MaxVertexShaderConst; + caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; + caps->PixelShader1xMaxValue = wined3d_caps->PixelShader1xMaxValue; + caps->DevCaps2 = wined3d_caps->DevCaps2; + caps->MaxNpatchTessellationLevel = wined3d_caps->MaxNpatchTessellationLevel; + caps->MasterAdapterOrdinal = wined3d_caps->MasterAdapterOrdinal; + caps->AdapterOrdinalInGroup = wined3d_caps->AdapterOrdinalInGroup; + caps->NumberOfAdaptersInGroup = wined3d_caps->NumberOfAdaptersInGroup; + caps->DeclTypes = wined3d_caps->DeclTypes; + caps->NumSimultaneousRTs = wined3d_caps->NumSimultaneousRTs; + caps->StretchRectFilterCaps = wined3d_caps->StretchRectFilterCaps; + caps->VS20Caps.Caps = wined3d_caps->VS20Caps.caps; + caps->VS20Caps.DynamicFlowControlDepth = wined3d_caps->VS20Caps.dynamic_flow_control_depth; + caps->VS20Caps.NumTemps = wined3d_caps->VS20Caps.temp_count; + caps->VS20Caps.StaticFlowControlDepth = wined3d_caps->VS20Caps.static_flow_control_depth; + caps->PS20Caps.Caps = wined3d_caps->PS20Caps.caps; + caps->PS20Caps.DynamicFlowControlDepth = wined3d_caps->PS20Caps.dynamic_flow_control_depth; + caps->PS20Caps.NumTemps = wined3d_caps->PS20Caps.temp_count; + caps->PS20Caps.StaticFlowControlDepth = wined3d_caps->PS20Caps.static_flow_control_depth; + caps->PS20Caps.NumInstructionSlots = wined3d_caps->PS20Caps.instruction_slot_count; + caps->VertexTextureFilterCaps = wined3d_caps->VertexTextureFilterCaps; + caps->MaxVShaderInstructionsExecuted = wined3d_caps->MaxVShaderInstructionsExecuted; + caps->MaxPShaderInstructionsExecuted = wined3d_caps->MaxPShaderInstructionsExecuted; + caps->MaxVertexShader30InstructionSlots = wined3d_caps->MaxVertexShader30InstructionSlots; + caps->MaxPixelShader30InstructionSlots = wined3d_caps->MaxPixelShader30InstructionSlots; + + /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps. */ + caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES; + + /* Filter wined3d caps. */ + caps->TextureFilterCaps &= texture_filter_caps; + caps->CubeTextureFilterCaps &= texture_filter_caps; + caps->VolumeTextureFilterCaps &= texture_filter_caps; + + caps->DevCaps &= + D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | + D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY| D3DDEVCAPS_TEXTUREVIDEOMEMORY | + D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM| + D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | + D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT| D3DDEVCAPS_CANBLTSYSTONONLOCAL | + D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES | + D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | D3DDEVCAPS_NPATCHES; + + caps->ShadeCaps &= + D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | + D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD; + + caps->RasterCaps &= + D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX | + D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | + D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | + D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | + D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | + D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE; + + caps->DevCaps2 &= + D3DDEVCAPS2_STREAMOFFSET | D3DDEVCAPS2_DMAPNPATCH | D3DDEVCAPS2_ADAPTIVETESSRTPATCH | + D3DDEVCAPS2_ADAPTIVETESSNPATCH | D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES | + D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH| D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; + + caps->Caps2 &= + D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED | + D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP; + + caps->VertexProcessingCaps &= + D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | + D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER | D3DVTXPCAPS_TWEENING | + D3DVTXPCAPS_TEXGEN_SPHEREMAP | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER; + + caps->TextureCaps &= + D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | + D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | + D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | + D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | + D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | + D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; + + caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); + caps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); + + if (caps->PixelShaderVersion > 3) + { + caps->PixelShaderVersion = D3DPS_VERSION(3, 0); + } + else + { + DWORD major = caps->PixelShaderVersion; + caps->PixelShaderVersion = D3DPS_VERSION(major, ps_minor_version[major]); + } + + if (caps->VertexShaderVersion > 3) + { + caps->VertexShaderVersion = D3DVS_VERSION(3, 0); + } + else + { + DWORD major = caps->VertexShaderVersion; + caps->VertexShaderVersion = D3DVS_VERSION(major, vs_minor_version[major]); + } +} + static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -399,7 +565,7 @@ static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - WINED3DCAPS *wined3d_caps; + WINED3DCAPS wined3d_caps; HRESULT hr; TRACE("iface %p, caps %p.\n", iface, caps); @@ -407,22 +573,13 @@ static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCA if (!caps) return D3DERR_INVALIDCALL; - if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps)))) - return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */ - memset(caps, 0, sizeof(*caps)); wined3d_mutex_lock(); - hr = wined3d_device_get_device_caps(device->wined3d_device, wined3d_caps); + hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); wined3d_mutex_unlock(); - WINECAPSTOD3D9CAPS(caps, wined3d_caps) - HeapFree(GetProcessHeap(), 0, wined3d_caps); - - /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */ - caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES; - - filter_caps(caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps); return hr; } @@ -602,44 +759,34 @@ static UINT WINAPI d3d9_device_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface) static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) { struct wined3d_resource_desc desc; + IDirect3DBaseTexture9 *texture; + struct d3d9_surface *surface; + IUnknown *parent; wined3d_resource_get_desc(resource, &desc); - if (desc.pool == WINED3D_POOL_DEFAULT) + if (desc.pool != WINED3D_POOL_DEFAULT) + return D3D_OK; + + if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) { - struct d3d9_surface *surface; - - if (desc.resource_type == WINED3D_RTYPE_TEXTURE_2D) - { - IUnknown *parent = wined3d_resource_get_parent(resource); - IDirect3DBaseTexture9 *texture; - - if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture9, (void **)&texture))) - { - IDirect3DBaseTexture9_Release(texture); - WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); - return D3DERR_INVALIDCALL; - } - - return D3D_OK; - } - - if (desc.resource_type != WINED3D_RTYPE_SURFACE) - { - WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); - return D3DERR_INVALIDCALL; - } - - surface = wined3d_resource_get_parent(resource); - if (surface->resource.refcount) - { - WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource); - return D3DERR_INVALIDCALL; - } - - WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource); + WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); + return D3DERR_INVALIDCALL; } - return D3D_OK; + parent = wined3d_resource_get_parent(resource); + if (parent && SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture9, (void **)&texture))) + { + IDirect3DBaseTexture9_Release(texture); + WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); + return D3DERR_INVALIDCALL; + } + + surface = wined3d_texture_get_sub_resource_parent(wined3d_texture_from_resource(resource), 0); + if (!surface->resource.refcount) + return D3D_OK; + + WARN("Surface %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface); + return D3DERR_INVALIDCALL; } static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device) @@ -756,12 +903,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex * if (device->device_state != D3D9_DEVICE_STATE_OK) return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : D3DERR_DEVICELOST; + if (dirty_region) + FIXME("Ignoring dirty_region %p.\n", dirty_region); + wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, src_rect, - dst_rect, dst_window_override, dirty_region, 0); - if (FAILED(hr)) + if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, 0))) { wined3d_mutex_unlock(); return hr; @@ -925,9 +1074,9 @@ static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface, struct d3d9_texture *object; HRESULT hr; - TRACE("iface %p, width %u, height %u, depth %u, levels %u\n", - iface, width, height, depth, levels); - TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", + TRACE("iface %p, width %u, height %u, depth %u, levels %u, " + "usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", + iface, width, height, depth, levels, usage, format, pool, texture, shared_handle); *texture = NULL; @@ -1105,7 +1254,6 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, void *user_mem) { - struct wined3d_resource *sub_resource; struct wined3d_resource_desc desc; struct d3d9_surface *surface_impl; struct wined3d_texture *texture; @@ -1127,10 +1275,13 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width desc.depth = 1; desc.size = 0; + if (is_gdi_compat_wined3dformat(desc.format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, - 1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture))) + 1, 1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); @@ -1139,8 +1290,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width return hr; } - sub_resource = wined3d_texture_get_sub_resource(texture, 0); - surface_impl = wined3d_resource_get_parent(sub_resource); + surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0); surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface; *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); @@ -1156,6 +1306,22 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width return D3D_OK; } +BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) +{ + switch (format) + { + case WINED3DFMT_B8G8R8A8_UNORM: + case WINED3DFMT_B8G8R8X8_UNORM: + case WINED3DFMT_B5G6R5_UNORM: + case WINED3DFMT_B5G5R5X1_UNORM: + case WINED3DFMT_B5G5R5A1_UNORM: + case WINED3DFMT_B8G8R8_UNORM: + return TRUE; + default: + return FALSE; + } +} + static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle) @@ -1233,14 +1399,7 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, iface, src_surface, src_rect, dst_surface, dst_point); if (src_rect) - { - src_box.left = src_rect->left; - src_box.top = src_rect->top; - src_box.right = src_rect->right; - src_box.bottom = src_rect->bottom; - src_box.front = 0; - src_box.back = 1; - } + wined3d_box_set(&src_box, src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1); wined3d_mutex_lock(); hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, @@ -1280,27 +1439,21 @@ static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface, { struct d3d9_surface *rt_impl = unsafe_impl_from_IDirect3DSurface9(render_target); struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface); - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *sub_resource; + struct wined3d_sub_resource_desc wined3d_desc; RECT dst_rect, src_rect; HRESULT hr; TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface); - wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); - dst_rect.left = 0; - dst_rect.top = 0; - dst_rect.right = wined3d_desc.width; - dst_rect.bottom = wined3d_desc.height; + if (!render_target || !dst_surface) + return D3DERR_INVALIDCALL; - sub_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); - src_rect.left = 0; - src_rect.top = 0; - src_rect.right = wined3d_desc.width; - src_rect.bottom = wined3d_desc.height; + wined3d_mutex_lock(); + wined3d_texture_get_sub_resource_desc(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &wined3d_desc); + SetRect(&dst_rect, 0, 0, wined3d_desc.width, wined3d_desc.height); + + wined3d_texture_get_sub_resource_desc(rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &wined3d_desc); + SetRect(&src_rect, 0, 0, wined3d_desc.width, wined3d_desc.height); /* TODO: Check surface sizes, pools, etc. */ if (wined3d_desc.multisample_type) @@ -1337,34 +1490,25 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface); struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface); + struct wined3d_sub_resource_desc src_desc, dst_desc; HRESULT hr = D3DERR_INVALIDCALL; - struct wined3d_resource_desc src_desc, dst_desc; - struct wined3d_resource *sub_resource; RECT d, s; TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n", iface, src_surface, src_rect, dst_surface, dst_rect, filter); wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &dst_desc); + wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &dst_desc); if (!dst_rect) { - d.left = 0; - d.top = 0; - d.right = dst_desc.width; - d.bottom = dst_desc.height; + SetRect(&d, 0, 0, dst_desc.width, dst_desc.height); dst_rect = &d; } - sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &src_desc); + wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &src_desc); if (!src_rect) { - s.left = 0; - s.top = 0; - s.right = src_desc.width; - s.bottom = src_desc.height; + SetRect(&s, 0, 0, src_desc.width, src_desc.height); src_rect = &s; } @@ -1421,20 +1565,20 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, }; struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface); - struct wined3d_resource *wined3d_resource; - struct wined3d_resource_desc desc; + struct wined3d_sub_resource_desc desc; + struct wined3d_rendertarget_view *rtv; HRESULT hr; TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, surface, rect, color); wined3d_mutex_lock(); - if (!(wined3d_resource = wined3d_texture_get_sub_resource(surface_impl->wined3d_texture, surface_impl->sub_resource_idx))) + if (FAILED(wined3d_texture_get_sub_resource_desc(surface_impl->wined3d_texture, + surface_impl->sub_resource_idx, &desc))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } - wined3d_resource_get_desc(wined3d_resource, &desc); if (desc.pool != WINED3D_POOL_DEFAULT) { @@ -1455,8 +1599,10 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, return D3DERR_INVALIDCALL; } + rtv = d3d9_surface_acquire_rendertarget_view(surface_impl); hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, - d3d9_surface_get_rendertarget_view(surface_impl), rect, &c); + rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0); + d3d9_surface_release_rendertarget_view(surface_impl, rtv); wined3d_mutex_unlock(); @@ -1512,6 +1658,7 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface); + struct wined3d_rendertarget_view *rtv; HRESULT hr; TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface); @@ -1524,13 +1671,20 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO if (!idx && !surface_impl) { - WARN("Trying to set render target 0 to NULL.\n"); - return D3DERR_INVALIDCALL; + WARN("Trying to set render target 0 to NULL.\n"); + return D3DERR_INVALIDCALL; + } + + if (surface_impl && d3d9_surface_get_device(surface_impl) != device) + { + WARN("Render target surface does not match device.\n"); + return D3DERR_INVALIDCALL; } wined3d_mutex_lock(); - hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, - surface_impl ? d3d9_surface_get_rendertarget_view(surface_impl) : NULL, TRUE); + rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; + hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE); + d3d9_surface_release_rendertarget_view(surface_impl, rtv); wined3d_mutex_unlock(); return hr; @@ -1577,12 +1731,14 @@ static HRESULT WINAPI d3d9_device_SetDepthStencilSurface(IDirect3DDevice9Ex *ifa { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *ds_impl = unsafe_impl_from_IDirect3DSurface9(depth_stencil); + struct wined3d_rendertarget_view *rtv; TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil); wined3d_mutex_lock(); - wined3d_device_set_depth_stencil_view(device->wined3d_device, - ds_impl ? d3d9_surface_get_rendertarget_view(ds_impl) : NULL); + rtv = ds_impl ? d3d9_surface_acquire_rendertarget_view(ds_impl) : NULL; + wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); + d3d9_surface_release_rendertarget_view(ds_impl, rtv); wined3d_mutex_unlock(); return D3D_OK; @@ -1665,6 +1821,12 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n", iface, rect_count, rects, flags, color, z, stencil); + if (rect_count && !rects) + { + WARN("count %u with NULL rects.\n", rect_count); + rect_count = 0; + } + wined3d_mutex_lock(); hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); wined3d_mutex_unlock(); @@ -1720,12 +1882,19 @@ static HRESULT WINAPI d3d9_device_MultiplyTransform(IDirect3DDevice9Ex *iface, static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D3DVIEWPORT9 *viewport) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); - /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */ + vp.x = viewport->X; + vp.y = viewport->Y; + vp.width = viewport->Width; + vp.height = viewport->Height; + vp.min_z = viewport->MinZ; + vp.max_z = viewport->MaxZ; + wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -1734,14 +1903,21 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEWPORT9 *viewport) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + struct wined3d_viewport wined3d_viewport; TRACE("iface %p, viewport %p.\n", iface, viewport); - /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */ wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); + viewport->X = wined3d_viewport.x; + viewport->Y = wined3d_viewport.y; + viewport->Width = wined3d_viewport.width; + viewport->Height = wined3d_viewport.height; + viewport->MinZ = wined3d_viewport.min_z; + viewport->MaxZ = wined3d_viewport.max_z; + return D3D_OK; } @@ -1948,7 +2124,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire wined3d_mutex_unlock(); if (FAILED(hr)) { - WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr); + WARN("Failed to end the state block, hr %#x.\n", hr); return hr; } @@ -2296,7 +2472,13 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, iface, primitive_type, start_vertex, primitive_count); wined3d_mutex_lock(); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + if (!device->has_vertex_declaration) + { + wined3d_mutex_unlock(); + WARN("Called without a valid vertex declaration set.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count_from_primitive_count(primitive_type, primitive_count)); wined3d_mutex_unlock(); @@ -2311,14 +2493,20 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); HRESULT hr; - TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n" + TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u, " "vertex_count %u, start_idx %u, primitive_count %u.\n", iface, primitive_type, base_vertex_idx, min_vertex_idx, vertex_count, start_idx, primitive_count); wined3d_mutex_lock(); + if (!device->has_vertex_declaration) + { + wined3d_mutex_unlock(); + WARN("Called without a valid vertex declaration set.\n"); + return D3DERR_INVALIDCALL; + } wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, vertex_count_from_primitive_count(primitive_type, primitive_count)); wined3d_mutex_unlock(); @@ -2336,13 +2524,13 @@ static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UIN UINT size = max(device->vertex_buffer_size * 2, min_size); struct wined3d_buffer *buffer; - TRACE("Growing vertex buffer to %u bytes\n", size); + TRACE("Growing vertex buffer to %u bytes.\n", size); hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer); if (FAILED(hr)) { - ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr); + ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x.\n", device, hr); return hr; } @@ -2362,9 +2550,11 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); HRESULT hr; UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; UINT size = vtx_count * stride; + struct wined3d_resource *vb; UINT vb_pos, align; - BYTE *buffer_data; TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", iface, primitive_type, primitive_count, data, stride); @@ -2377,6 +2567,13 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, wined3d_mutex_lock(); + if (!device->has_vertex_declaration) + { + wined3d_mutex_unlock(); + WARN("Called without a valid vertex declaration set.\n"); + return D3DERR_INVALIDCALL; + } + hr = d3d9_device_prepare_vertex_buffer(device, size); if (FAILED(hr)) goto done; @@ -2389,19 +2586,21 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &buffer_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, data, size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, data, size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); if (FAILED(hr)) goto done; - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); @@ -2420,13 +2619,13 @@ static HRESULT d3d9_device_prepare_index_buffer(struct d3d9_device *device, UINT UINT size = max(device->index_buffer_size * 2, min_size); struct wined3d_buffer *buffer; - TRACE("Growing index buffer to %u bytes\n", size); + TRACE("Growing index buffer to %u bytes.\n", size); hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer); if (FAILED(hr)) { - ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr); + ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x.\n", device, hr); return hr; } @@ -2445,31 +2644,37 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa UINT primitive_count, const void *index_data, D3DFORMAT index_format, const void *vertex_data, UINT vertex_stride) { - struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - HRESULT hr; - BYTE *buffer_data; - UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4; - UINT idx_size = idx_count * idx_fmt_size; - UINT ib_pos; - UINT vtx_size = vertex_count * vertex_stride; - UINT vb_pos, align; + UINT idx_size = idx_count * idx_fmt_size; + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *ib, *vb; + UINT vb_pos, ib_pos, align; + HRESULT hr; - TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u,\n" + TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u, " "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n", iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, index_data, index_format, vertex_data, vertex_stride); if (!primitive_count) { - WARN("primitive_count is 0, returning D3D_OK\n"); + WARN("primitive_count is 0, returning D3D_OK.\n"); return D3D_OK; } wined3d_mutex_lock(); + if (!device->has_vertex_declaration) + { + wined3d_mutex_unlock(); + WARN("Called without a valid vertex declaration set.\n"); + return D3DERR_INVALIDCALL; + } + hr = d3d9_device_prepare_vertex_buffer(device, vtx_size); if (FAILED(hr)) goto done; @@ -2482,12 +2687,14 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &buffer_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + vtx_size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, vertex_data, vtx_size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + vtx_size; hr = d3d9_device_prepare_index_buffer(device, idx_size); @@ -2502,12 +2709,14 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa else ib_pos += align; - hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &buffer_data, - ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = ib_pos; + wined3d_box.right = ib_pos + idx_size; + ib = wined3d_buffer_get_resource(device->index_buffer); + if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, + ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(buffer_data, index_data, idx_size); - wined3d_buffer_unmap(device->index_buffer); + memcpy(wined3d_map_desc.data, index_data, idx_size); + wined3d_resource_unmap(ib, 0); device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride); @@ -2515,14 +2724,14 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa goto done; wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, - wined3dformat_from_d3dformat(index_format)); - wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride); + wined3dformat_from_d3dformat(index_format), 0); + wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); - wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN); + wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, 0); done: @@ -2583,6 +2792,7 @@ static HRESULT WINAPI d3d9_device_SetVertexDeclaration(IDirect3DDevice9Ex *iface wined3d_mutex_lock(); wined3d_device_set_vertex_declaration(device->wined3d_device, decl_impl ? decl_impl->wined3d_declaration : NULL); + device->has_vertex_declaration = !!decl_impl; wined3d_mutex_unlock(); return D3D_OK; @@ -2706,6 +2916,7 @@ static HRESULT WINAPI d3d9_device_SetFVF(IDirect3DDevice9Ex *iface, DWORD fvf) } wined3d_device_set_vertex_declaration(device->wined3d_device, decl); + device->has_vertex_declaration = TRUE; wined3d_mutex_unlock(); return D3D_OK; @@ -2820,7 +3031,8 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *i } wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_f(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_vs_consts_f(device->wined3d_device, + reg_idx, count, (const struct wined3d_vec4 *)data); wined3d_mutex_unlock(); return hr; @@ -2842,7 +3054,8 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *i } wined3d_mutex_lock(); - hr = wined3d_device_get_vs_consts_f(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_vs_consts_f(device->wined3d_device, + reg_idx, count, (struct wined3d_vec4 *)data); wined3d_mutex_unlock(); return hr; @@ -2857,7 +3070,8 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantI(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_i(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_vs_consts_i(device->wined3d_device, + reg_idx, count, (const struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -2872,7 +3086,8 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantI(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_vs_consts_i(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_vs_consts_i(device->wined3d_device, + reg_idx, count, (struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -2887,7 +3102,7 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantB(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -2902,7 +3117,7 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantB(IDirect3DDevice9Ex *i TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_vs_consts_b(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_vs_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -2996,8 +3211,7 @@ static HRESULT WINAPI d3d9_device_SetIndices(IDirect3DDevice9Ex *iface, IDirect3 wined3d_mutex_lock(); wined3d_device_set_index_buffer(device->wined3d_device, - ib ? ib->wined3d_buffer : NULL, - ib ? ib->format : WINED3DFMT_UNKNOWN); + ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); wined3d_mutex_unlock(); return D3D_OK; @@ -3016,7 +3230,7 @@ static HRESULT WINAPI d3d9_device_GetIndices(IDirect3DDevice9Ex *iface, IDirect3 return D3DERR_INVALIDCALL; wined3d_mutex_lock(); - if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format))) + if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, NULL))) { buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); *buffer = &buffer_impl->IDirect3DIndexBuffer9_iface; @@ -3113,7 +3327,8 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantF(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_f(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_ps_consts_f(device->wined3d_device, + reg_idx, count, (const struct wined3d_vec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3128,7 +3343,8 @@ static HRESULT WINAPI d3d9_device_GetPixelShaderConstantF(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_ps_consts_f(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_ps_consts_f(device->wined3d_device, + reg_idx, count, (struct wined3d_vec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3143,7 +3359,8 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantI(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_i(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_ps_consts_i(device->wined3d_device, + reg_idx, count, (const struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3158,7 +3375,8 @@ static HRESULT WINAPI d3d9_device_GetPixelShaderConstantI(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_ps_consts_i(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_ps_consts_i(device->wined3d_device, + reg_idx, count, (struct wined3d_ivec4 *)data); wined3d_mutex_unlock(); return hr; @@ -3173,7 +3391,7 @@ static HRESULT WINAPI d3d9_device_SetPixelShaderConstantB(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -3188,7 +3406,7 @@ static HRESULT WINAPI d3d9_device_GetPixelShaderConstantB(IDirect3DDevice9Ex *if TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); wined3d_mutex_lock(); - hr = wined3d_device_get_ps_consts_b(device->wined3d_device, reg_idx, data, count); + hr = wined3d_device_get_ps_consts_b(device->wined3d_device, reg_idx, count, data); wined3d_mutex_unlock(); return hr; @@ -3256,7 +3474,7 @@ static HRESULT WINAPI d3d9_device_ComposeRects(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs, UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y) { - FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n" + FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u, " "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n", iface, src_surface, dst_surface, src_descs, rect_count, dst_descs, operation, offset_x, offset_y); @@ -3279,11 +3497,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex if (device->device_state != D3D9_DEVICE_STATE_OK) return S_PRESENT_OCCLUDED; + if (dirty_region) + FIXME("Ignoring dirty_region %p.\n", dirty_region); + wined3d_mutex_lock(); for (i = 0; i < device->implicit_swapchain_count; ++i) { - if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, src_rect, - dst_rect, dst_window_override, dirty_region, flags))) + if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, flags))) { wined3d_mutex_unlock(); return hr; @@ -3366,7 +3587,7 @@ static HRESULT WINAPI d3d9_device_CreateRenderTargetEx(IDirect3DDevice9Ex *iface UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) { - FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n" + FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n", iface, width, height, format, multisample_type, multisample_quality, lockable, surface, shared_handle, usage); @@ -3412,6 +3633,7 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex if (discard) flags |= WINED3D_TEXTURE_CREATE_DISCARD; + *surface = NULL; return d3d9_device_create_surface(device, width, height, format, flags, surface, D3DUSAGE_DEPTHSTENCIL | usage, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); } @@ -3423,6 +3645,21 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_ResetEx(IDirect3DDevice9Ex * TRACE("iface %p, present_parameters %p, mode %p.\n", iface, present_parameters, mode); + if (!present_parameters->Windowed == !mode) + { + WARN("Mode can be passed if and only if Windowed is FALSE.\n"); + return D3DERR_INVALIDCALL; + } + + if (mode && (mode->Width != present_parameters->BackBufferWidth + || mode->Height != present_parameters->BackBufferHeight)) + { + WARN("Mode and back buffer mismatch (mode %ux%u, backbuffer %ux%u).\n", + mode->Width, mode->Height, + present_parameters->BackBufferWidth, present_parameters->BackBufferHeight); + return D3DERR_INVALIDCALL; + } + return d3d9_device_reset(device, present_parameters, mode); } @@ -3669,26 +3906,28 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent * } static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture) + void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, + struct wined3d_texture **texture) { struct d3d9_device *device = device_from_device_parent(device_parent); struct d3d9_surface *d3d_surface; HRESULT hr; - TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n", - device_parent, container_parent, desc, texture); + TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", + device_parent, container_parent, desc, texture_flags, texture); if (container_parent == device_parent) container_parent = &device->IDirect3DDevice9Ex_iface; - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, - WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, + texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, + &d3d9_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; } - d3d_surface = wined3d_resource_get_parent(wined3d_texture_get_sub_resource(*texture, 0)); + d3d_surface = wined3d_texture_get_sub_resource_parent(*texture, 0); d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface; return hr; diff --git a/reactos/dll/directx/wine/d3d9/directx.c b/reactos/dll/directx/wine/d3d9/directx.c index 821af7c8343..2674a13b1bb 100644 --- a/reactos/dll/directx/wine/d3d9/directx.c +++ b/reactos/dll/directx/wine/d3d9/directx.c @@ -254,27 +254,20 @@ static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter, usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { - case D3DRTYPE_SURFACE: - wined3d_rtype = WINED3D_RTYPE_SURFACE; - break; - - case D3DRTYPE_VOLUME: - wined3d_rtype = WINED3D_RTYPE_VOLUME; - break; - + case D3DRTYPE_CUBETEXTURE: + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; case D3DRTYPE_TEXTURE: + usage |= WINED3DUSAGE_TEXTURE; + case D3DRTYPE_SURFACE: wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; break; case D3DRTYPE_VOLUMETEXTURE: + case D3DRTYPE_VOLUME: + usage |= WINED3DUSAGE_TEXTURE; wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; break; - case D3DRTYPE_CUBETEXTURE: - wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; - usage |= WINED3DUSAGE_LEGACY_CUBEMAP; - break; - case D3DRTYPE_VERTEXBUFFER: case D3DRTYPE_INDEXBUFFER: wined3d_rtype = WINED3D_RTYPE_BUFFER; @@ -350,87 +343,10 @@ static HRESULT WINAPI d3d9_CheckDeviceFormatConversion(IDirect3D9Ex *iface, UINT return hr; } -void filter_caps(D3DCAPS9* pCaps) -{ - DWORD ps_minor_version[] = {0, 4, 0, 0}; - DWORD vs_minor_version[] = {0, 1, 0, 0}; - DWORD textureFilterCaps = - D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | - D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | D3DPTFILTERCAPS_MINFGAUSSIANQUAD| - D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | - D3DPTFILTERCAPS_MAGFLINEAR |D3DPTFILTERCAPS_MAGFANISOTROPIC|D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD| - D3DPTFILTERCAPS_MAGFGAUSSIANQUAD; - pCaps->TextureFilterCaps &= textureFilterCaps; - pCaps->CubeTextureFilterCaps &= textureFilterCaps; - pCaps->VolumeTextureFilterCaps &= textureFilterCaps; - - pCaps->DevCaps &= - D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | - D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY| D3DDEVCAPS_TEXTUREVIDEOMEMORY | - D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM| - D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | - D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT| D3DDEVCAPS_CANBLTSYSTONONLOCAL | - D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES | - D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | D3DDEVCAPS_NPATCHES; - - pCaps->ShadeCaps &= - D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | - D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD; - - pCaps->RasterCaps &= - D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX | - D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | - D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | - D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | - D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | - D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE; - - pCaps->DevCaps2 &= - D3DDEVCAPS2_STREAMOFFSET | D3DDEVCAPS2_DMAPNPATCH | D3DDEVCAPS2_ADAPTIVETESSRTPATCH | - D3DDEVCAPS2_ADAPTIVETESSNPATCH | D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES | - D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH| D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; - - pCaps->Caps2 &= - D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED | - D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP; - - pCaps->VertexProcessingCaps &= - D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | - D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER | D3DVTXPCAPS_TWEENING | - D3DVTXPCAPS_TEXGEN_SPHEREMAP | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER; - - pCaps->TextureCaps &= - D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | - D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | - D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | - D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | - D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | - D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; - - pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); - pCaps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, pCaps->NumSimultaneousRTs); - - if (pCaps->PixelShaderVersion > 3) - pCaps->PixelShaderVersion = D3DPS_VERSION(3,0); - else - { - DWORD major = pCaps->PixelShaderVersion; - pCaps->PixelShaderVersion = D3DPS_VERSION(major,ps_minor_version[major]); - } - - if (pCaps->VertexShaderVersion > 3) - pCaps->VertexShaderVersion = D3DVS_VERSION(3,0); - else - { - DWORD major = pCaps->VertexShaderVersion; - pCaps->VertexShaderVersion = D3DVS_VERSION(major,vs_minor_version[major]); - } -} - static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS9 *caps) { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); - WINED3DCAPS *wined3d_caps; + WINED3DCAPS wined3d_caps; HRESULT hr; TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps); @@ -438,21 +354,13 @@ static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DD if (!caps) return D3DERR_INVALIDCALL; - if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS)))) - return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/ memset(caps, 0, sizeof(*caps)); wined3d_mutex_lock(); - hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, wined3d_caps); + hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, &wined3d_caps); wined3d_mutex_unlock(); - WINECAPSTOD3D9CAPS(caps, wined3d_caps) - HeapFree(GetProcessHeap(), 0, wined3d_caps); - - /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */ - caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES; - - filter_caps(caps); + d3dcaps_from_wined3dcaps(caps, &wined3d_caps); return hr; } @@ -502,7 +410,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDevice(IDirect3D9Ex *iface, U } TRACE("Created device %p.\n", object); - *device = (IDirect3DDevice9 *)object; + *device = (IDirect3DDevice9 *)&object->IDirect3DDevice9Ex_iface; return D3D_OK; } @@ -668,7 +576,8 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl = BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) { DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER - | WINED3D_SRGB_READ_WRITE_CONTROL; + | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR + | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING; if (!extended) flags |= WINED3D_VIDMEM_ACCOUNTING; diff --git a/reactos/dll/directx/wine/d3d9/query.c b/reactos/dll/directx/wine/d3d9/query.c index 606e84d07cf..90187566bd6 100644 --- a/reactos/dll/directx/wine/d3d9/query.c +++ b/reactos/dll/directx/wine/d3d9/query.c @@ -105,20 +105,10 @@ static D3DQUERYTYPE WINAPI d3d9_query_GetType(IDirect3DQuery9 *iface) static DWORD WINAPI d3d9_query_GetDataSize(IDirect3DQuery9 *iface) { struct d3d9_query *query = impl_from_IDirect3DQuery9(iface); - enum wined3d_query_type type; - DWORD ret; TRACE("iface %p.\n", iface); - wined3d_mutex_lock(); - type = wined3d_query_get_type(query->wined3d_query); - if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) - ret = sizeof(BOOL); - else - ret = wined3d_query_get_data_size(query->wined3d_query); - wined3d_mutex_unlock(); - - return ret; + return query->data_size; } static HRESULT WINAPI d3d9_query_Issue(IDirect3DQuery9 *iface, DWORD flags) @@ -154,7 +144,8 @@ static HRESULT WINAPI d3d9_query_GetData(IDirect3DQuery9 *iface, void *data, DWO size = sizeof(data_disjoint.disjoint); hr = wined3d_query_get_data(query->wined3d_query, &data_disjoint, sizeof(data_disjoint), flags); - memcpy(data, &data_disjoint.disjoint, size); + if (SUCCEEDED(hr)) + memcpy(data, &data_disjoint.disjoint, size); } else { @@ -162,6 +153,15 @@ static HRESULT WINAPI d3d9_query_GetData(IDirect3DQuery9 *iface, void *data, DWO } wined3d_mutex_unlock(); + if (hr == D3DERR_INVALIDCALL) + { + if (data) + { + memset(data, 0, size); + memset(data, 0xdd, min(size, query->data_size)); + } + return S_OK; + } return hr; } @@ -182,18 +182,32 @@ HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUER { HRESULT hr; + if (type > D3DQUERYTYPE_MEMORYPRESSURE) + { + WARN("Invalid query type %#x.\n", type); + return D3DERR_NOTAVAILABLE; + } + query->IDirect3DQuery9_iface.lpVtbl = &d3d9_query_vtbl; query->refcount = 1; wined3d_mutex_lock(); - hr = wined3d_query_create(device->wined3d_device, type, query, &query->wined3d_query); - wined3d_mutex_unlock(); - if (FAILED(hr)) + if (FAILED(hr = wined3d_query_create(device->wined3d_device, type, + query, &d3d9_null_wined3d_parent_ops, &query->wined3d_query))) { + wined3d_mutex_unlock(); WARN("Failed to create wined3d query, hr %#x.\n", hr); return hr; } + if (type == D3DQUERYTYPE_OCCLUSION) + query->data_size = sizeof(DWORD); + else if (type == D3DQUERYTYPE_TIMESTAMPDISJOINT) + query->data_size = sizeof(BOOL); + else + query->data_size = wined3d_query_get_data_size(query->wined3d_query); + wined3d_mutex_unlock(); + query->parent_device = &device->IDirect3DDevice9Ex_iface; IDirect3DDevice9Ex_AddRef(query->parent_device); diff --git a/reactos/dll/directx/wine/d3d9/shader.c b/reactos/dll/directx/wine/d3d9/shader.c index 59ccd2dcd1a..75dfc0f3941 100644 --- a/reactos/dll/directx/wine/d3d9/shader.c +++ b/reactos/dll/directx/wine/d3d9/shader.c @@ -140,8 +140,11 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device * shader->IDirect3DVertexShader9_iface.lpVtbl = &d3d9_vertexshader_vtbl; desc.byte_code = byte_code; - desc.input_signature = NULL; - desc.output_signature = NULL; + desc.byte_code_size = ~(size_t)0; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; + desc.input_signature.element_count = 0; + desc.output_signature.element_count = 0; + desc.patch_constant_signature.element_count = 0; desc.max_version = 3; wined3d_mutex_lock(); @@ -291,8 +294,11 @@ HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *de shader->IDirect3DPixelShader9_iface.lpVtbl = &d3d9_pixelshader_vtbl; desc.byte_code = byte_code; - desc.input_signature = NULL; - desc.output_signature = NULL; + desc.byte_code_size = ~(size_t)0; + desc.format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1; + desc.input_signature.element_count = 0; + desc.output_signature.element_count = 0; + desc.patch_constant_signature.element_count = 0; desc.max_version = 3; wined3d_mutex_lock(); diff --git a/reactos/dll/directx/wine/d3d9/surface.c b/reactos/dll/directx/wine/d3d9/surface.c index 3b07175115a..47b52679109 100644 --- a/reactos/dll/directx/wine/d3d9/surface.c +++ b/reactos/dll/directx/wine/d3d9/surface.c @@ -90,7 +90,7 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface) if (!surface->resource.refcount) { - ERR("Surface doesn't have any references.\n"); + WARN("Surface does not have any references.\n"); return 0; } @@ -179,7 +179,7 @@ static void WINAPI d3d9_surface_PreLoad(IDirect3DSurface9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(surface->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(surface->wined3d_texture)); wined3d_mutex_unlock(); } @@ -210,18 +210,16 @@ static HRESULT WINAPI d3d9_surface_GetContainer(IDirect3DSurface9 *iface, REFIID static HRESULT WINAPI d3d9_surface_GetDesc(IDirect3DSurface9 *iface, D3DSURFACE_DESC *desc) { struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface); - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *sub_resource; + struct wined3d_sub_resource_desc wined3d_desc; TRACE("iface %p, desc %p.\n", iface, desc); wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &wined3d_desc); wined3d_mutex_unlock(); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -244,17 +242,10 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, iface, locked_rect, wine_dbgstr_rect(rect), flags); if (rect) - { - box.left = rect->left; - box.top = rect->top; - box.right = rect->right; - box.bottom = rect->bottom; - box.front = 0; - box.back = 1; - } + wined3d_box_set(&box, rect->left, rect->top, rect->right, rect->bottom, 0, 1); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, + hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags); wined3d_mutex_unlock(); @@ -275,14 +266,19 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); wined3d_mutex_unlock(); - switch(hr) + if (hr == WINEDDERR_NOTLOCKED) { - case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL; - default: return hr; + D3DRESOURCETYPE type; + if (surface->texture) + type = IDirect3DBaseTexture9_GetType(&surface->texture->IDirect3DBaseTexture9_iface); + else + type = D3DRTYPE_SURFACE; + hr = type == D3DRTYPE_TEXTURE ? D3D_OK : D3DERR_INVALIDCALL; } + return hr; } static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc) @@ -292,13 +288,6 @@ static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc) TRACE("iface %p, dc %p.\n", iface, dc); - if (!surface->getdc_supported) - { - WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n"); - /* Don't touch the DC */ - return D3DERR_INVALIDCALL; - } - wined3d_mutex_lock(); hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); wined3d_mutex_unlock(); @@ -317,11 +306,7 @@ static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc) hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); wined3d_mutex_unlock(); - switch (hr) - { - case WINEDDERR_NODC: return D3DERR_INVALIDCALL; - default: return hr; - } + return hr; } static const struct IDirect3DSurface9Vtbl d3d9_surface_vtbl = @@ -363,7 +348,6 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) { - struct wined3d_resource_desc desc; IDirect3DBaseTexture9 *texture; surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; @@ -381,23 +365,6 @@ void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_ IDirect3DBaseTexture9_Release(texture); } - wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &desc); - switch (d3dformat_from_wined3dformat(desc.format)) - { - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - case D3DFMT_R8G8B8: - surface->getdc_supported = TRUE; - break; - - default: - surface->getdc_supported = FALSE; - break; - } - *parent_ops = &d3d9_surface_wined3d_parent_ops; } @@ -423,10 +390,22 @@ static const struct wined3d_parent_ops d3d9_view_wined3d_parent_ops = view_wined3d_object_destroyed, }; -struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) +struct d3d9_device *d3d9_surface_get_device(const struct d3d9_surface *surface) +{ + IDirect3DDevice9Ex *device; + device = surface->texture ? surface->texture->parent_device : surface->parent_device; + return impl_from_IDirect3DDevice9Ex(device); +} + +struct wined3d_rendertarget_view *d3d9_surface_acquire_rendertarget_view(struct d3d9_surface *surface) { HRESULT hr; + /* The surface reference count can be equal to 0 when this function is + * called. In order to properly manage the render target view reference + * count, we temporarily increment the surface reference count. */ + d3d9_surface_AddRef(&surface->IDirect3DSurface9_iface); + if (surface->wined3d_rtv) return surface->wined3d_rtv; @@ -434,6 +413,7 @@ struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9 surface->sub_resource_idx, surface, &d3d9_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); + d3d9_surface_Release(&surface->IDirect3DSurface9_iface); return NULL; } @@ -443,6 +423,13 @@ struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9 return surface->wined3d_rtv; } +void d3d9_surface_release_rendertarget_view(struct d3d9_surface *surface, + struct wined3d_rendertarget_view *rtv) +{ + if (rtv) + d3d9_surface_Release(&surface->IDirect3DSurface9_iface); +} + struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) { if (!iface) diff --git a/reactos/dll/directx/wine/d3d9/swapchain.c b/reactos/dll/directx/wine/d3d9/swapchain.c index d0e931e2aa7..7b2dc7ea4fe 100644 --- a/reactos/dll/directx/wine/d3d9/swapchain.c +++ b/reactos/dll/directx/wine/d3d9/swapchain.c @@ -87,8 +87,15 @@ static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9Ex *iface) static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); - ULONG refcount = InterlockedDecrement(&swapchain->refcount); + ULONG refcount; + if (!swapchain->refcount) + { + WARN("Swapchain does not have any references.\n"); + return 0; + } + + refcount = InterlockedDecrement(&swapchain->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) @@ -122,9 +129,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChai if (device->device_state != D3D9_DEVICE_STATE_OK) return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : D3DERR_DEVICELOST; + if (dirty_region) + FIXME("Ignoring dirty_region %p.\n", dirty_region); + wined3d_mutex_lock(); - hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect, - dst_rect, dst_window_override, dirty_region, flags); + hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, + src_rect, dst_rect, dst_window_override, flags); wined3d_mutex_unlock(); return hr; @@ -149,7 +159,6 @@ static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9Ex *iface, UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); - struct wined3d_resource *wined3d_resource; struct wined3d_texture *wined3d_texture; struct d3d9_surface *surface_impl; HRESULT hr = D3D_OK; @@ -168,8 +177,7 @@ static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9Ex *iface, wined3d_mutex_lock(); if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx))) { - wined3d_resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); - surface_impl = wined3d_resource_get_parent(wined3d_resource); + surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); *backbuffer = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*backbuffer); } diff --git a/reactos/dll/directx/wine/d3d9/texture.c b/reactos/dll/directx/wine/d3d9/texture.c index b3c36095c37..5e9979a4ceb 100644 --- a/reactos/dll/directx/wine/d3d9/texture.c +++ b/reactos/dll/directx/wine/d3d9/texture.c @@ -22,17 +22,17 @@ static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface) { - return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); } static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface) { - return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); } static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface) { - return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); + return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); } static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out) @@ -186,7 +186,7 @@ static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -282,21 +282,16 @@ static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -313,19 +308,17 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface, UINT level, IDirect3DSurface9 **surface) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } - surface_impl = wined3d_resource_get_parent(sub_resource); *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); wined3d_mutex_unlock(); @@ -337,7 +330,6 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; HRESULT hr; @@ -345,13 +337,10 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, iface, level, locked_rect, rect, flags); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; else - { - surface_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags); - } wined3d_mutex_unlock(); return hr; @@ -360,20 +349,16 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; HRESULT hr; TRACE("iface %p, level %u.\n", iface, level); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; else - { - surface_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface); - } wined3d_mutex_unlock(); return hr; @@ -394,12 +379,7 @@ static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, con { struct wined3d_box dirty_region; - dirty_region.left = dirty_rect->left; - dirty_region.top = dirty_rect->top; - dirty_region.right = dirty_rect->right; - dirty_region.bottom = dirty_rect->bottom; - dirty_region.front = 0; - dirty_region.back = 1; + wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region); } wined3d_mutex_unlock(); @@ -590,7 +570,7 @@ static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -687,9 +667,9 @@ static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; DWORD level_count; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); @@ -701,15 +681,10 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac return D3DERR_INVALIDCALL; } - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_SURFACE; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->MultiSampleType = wined3d_desc.multisample_type; @@ -726,7 +701,6 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; UINT sub_resource_idx; DWORD level_count; @@ -742,13 +716,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 } sub_resource_idx = level_count * face + level; - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } - surface_impl = wined3d_resource_get_parent(sub_resource); *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); wined3d_mutex_unlock(); @@ -761,7 +734,6 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface, DWORD flags) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; UINT sub_resource_idx; HRESULT hr; @@ -771,13 +743,10 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface, wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) hr = D3DERR_INVALIDCALL; else - { - surface_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags); - } wined3d_mutex_unlock(); return hr; @@ -787,7 +756,6 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface, D3DCUBEMAP_FACES face, UINT level) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_surface *surface_impl; UINT sub_resource_idx; HRESULT hr; @@ -796,13 +764,10 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface, wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx))) + if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) hr = D3DERR_INVALIDCALL; else - { - surface_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface); - } wined3d_mutex_unlock(); return hr; @@ -824,12 +789,7 @@ static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *ifa { struct wined3d_box dirty_region; - dirty_region.left = dirty_rect->left; - dirty_region.top = dirty_rect->top; - dirty_region.right = dirty_rect->right; - dirty_region.bottom = dirty_rect->bottom; - dirty_region.front = 0; - dirty_region.back = 1; + wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region); } wined3d_mutex_unlock(); @@ -1007,7 +967,7 @@ static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); } @@ -1104,21 +1064,16 @@ static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc) { struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; + struct wined3d_sub_resource_desc wined3d_desc; + HRESULT hr; TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else + if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_VOLUME; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Width = wined3d_desc.width; @@ -1134,19 +1089,17 @@ static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *if UINT level, IDirect3DVolume9 **volume) { struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_volume *volume_impl; TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) { wined3d_mutex_unlock(); return D3DERR_INVALIDCALL; } - volume_impl = wined3d_resource_get_parent(sub_resource); *volume = &volume_impl->IDirect3DVolume9_iface; IDirect3DVolume9_AddRef(*volume); wined3d_mutex_unlock(); @@ -1158,7 +1111,6 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface, UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags) { struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_volume *volume_impl; HRESULT hr; @@ -1166,13 +1118,10 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface, iface, level, locked_box, box, flags); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; else - { - volume_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags); - } wined3d_mutex_unlock(); return hr; @@ -1181,20 +1130,16 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface, static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level) { struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - struct wined3d_resource *sub_resource; struct d3d9_volume *volume_impl; HRESULT hr; TRACE("iface %p, level %u.\n", iface, level); wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; else - { - volume_impl = wined3d_resource_get_parent(sub_resource); hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface); - } wined3d_mutex_unlock(); return hr; @@ -1299,6 +1244,9 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (is_gdi_compat_wined3dformat(desc.format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (!levels) { if (usage & D3DUSAGE_AUTOGENMIPMAP) @@ -1308,7 +1256,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, } wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1349,6 +1297,9 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (is_gdi_compat_wined3dformat(desc.format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (!levels) { if (usage & D3DUSAGE_AUTOGENMIPMAP) @@ -1358,7 +1309,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic } wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1404,7 +1355,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev } wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, + hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0, NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) diff --git a/reactos/dll/directx/wine/d3d9/vertexdeclaration.c b/reactos/dll/directx/wine/d3d9/vertexdeclaration.c index 5b3ae915c07..e9248be5ea4 100644 --- a/reactos/dll/directx/wine/d3d9/vertexdeclaration.c +++ b/reactos/dll/directx/wine/d3d9/vertexdeclaration.c @@ -42,8 +42,8 @@ d3d_dtype_lookup[] = /* D3DDECLTYPE_SHORT4N */ {WINED3DFMT_R16G16B16A16_SNORM, 4, sizeof(short int)}, /* D3DDECLTYPE_USHORT2N */ {WINED3DFMT_R16G16_UNORM, 2, sizeof(short int)}, /* D3DDECLTYPE_USHORT4N */ {WINED3DFMT_R16G16B16A16_UNORM, 4, sizeof(short int)}, - /* D3DDECLTYPE_UDEC3 */ {WINED3DFMT_R10G10B10A2_UINT, 3, sizeof(short int)}, - /* D3DDECLTYPE_DEC3N */ {WINED3DFMT_R10G10B10A2_SNORM, 3, sizeof(short int)}, + /* D3DDECLTYPE_UDEC3 */ {WINED3DFMT_R10G10B10X2_UINT, 3, sizeof(short int)}, + /* D3DDECLTYPE_DEC3N */ {WINED3DFMT_R10G10B10X2_SNORM, 3, sizeof(short int)}, /* D3DDECLTYPE_FLOAT16_2 */ {WINED3DFMT_R16G16_FLOAT, 2, sizeof(short int)}, /* D3DDECLTYPE_FLOAT16_4 */ {WINED3DFMT_R16G16B16A16_FLOAT, 4, sizeof(short int)} }; diff --git a/reactos/dll/directx/wine/d3d9/volume.c b/reactos/dll/directx/wine/d3d9/volume.c index 245612ee7a7..5c6a068811e 100644 --- a/reactos/dll/directx/wine/d3d9/volume.c +++ b/reactos/dll/directx/wine/d3d9/volume.c @@ -113,18 +113,16 @@ static HRESULT WINAPI d3d9_volume_GetContainer(IDirect3DVolume9 *iface, REFIID r static HRESULT WINAPI d3d9_volume_GetDesc(IDirect3DVolume9 *iface, D3DVOLUME_DESC *desc) { struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface); - struct wined3d_resource_desc wined3d_desc; - struct wined3d_resource *sub_resource; + struct wined3d_sub_resource_desc wined3d_desc; TRACE("iface %p, desc %p.\n", iface, desc); wined3d_mutex_lock(); - sub_resource = wined3d_texture_get_sub_resource(volume->wined3d_texture, volume->sub_resource_idx); - wined3d_resource_get_desc(sub_resource, &wined3d_desc); + wined3d_texture_get_sub_resource_desc(volume->wined3d_texture, volume->sub_resource_idx, &wined3d_desc); wined3d_mutex_unlock(); desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; + desc->Type = D3DRTYPE_VOLUME; desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; desc->Pool = wined3d_desc.pool; desc->Width = wined3d_desc.width; @@ -145,8 +143,9 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface, iface, locked_box, box, flags); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); + if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), + volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags))) + map_desc.data = NULL; wined3d_mutex_unlock(); locked_box->RowPitch = map_desc.row_pitch; @@ -164,9 +163,11 @@ static HRESULT WINAPI d3d9_volume_UnlockBox(IDirect3DVolume9 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); wined3d_mutex_unlock(); + if (hr == WINEDDERR_NOTLOCKED) + return D3DERR_INVALIDCALL; return hr; } diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c index d99d9e0056a..9712bb53aeb 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.c +++ b/reactos/dll/directx/wine/ddraw/ddraw.c @@ -23,6 +23,8 @@ #include "ddraw_private.h" +#include + static const struct ddraw *exclusive_ddraw; static HWND exclusive_window; @@ -358,7 +360,7 @@ static ULONG WINAPI d3d1_AddRef(IDirect3D *iface) return ddraw1_AddRef(&This->IDirectDraw_iface); } -void ddraw_destroy_swapchain(struct ddraw *ddraw) +static void ddraw_destroy_swapchain(struct ddraw *ddraw) { TRACE("Destroying the swapchain.\n"); @@ -630,6 +632,7 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; swapchain_desc.device_window = window; swapchain_desc.windowed = windowed; + swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; if (!(ddraw->flags & DDRAW_NO3D)) hr = ddraw_attach_d3d_device(ddraw, &swapchain_desc); @@ -651,6 +654,9 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win wined3d_swapchain_incref(ddraw->wined3d_swapchain); ddraw_set_swapchain_window(ddraw, window); + if (ddraw->primary && ddraw->primary->palette) + wined3d_swapchain_set_palette(ddraw->wined3d_swapchain, ddraw->primary->palette->wined3d_palette); + return DD_OK; } @@ -688,6 +694,8 @@ static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface) if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, NULL))) ddraw->flags &= ~DDRAW_RESTORE_MODE; + InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_OK); + wined3d_mutex_unlock(); return hr; @@ -888,7 +896,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, if ((cooplevel & DDSCL_FULLSCREEN) != (ddraw->cooperative_level & DDSCL_FULLSCREEN) || window != ddraw->dest_window) { if (ddraw->cooperative_level & DDSCL_FULLSCREEN) - wined3d_device_restore_fullscreen_window(ddraw->wined3d_device, ddraw->dest_window); + wined3d_device_restore_fullscreen_window(ddraw->wined3d_device, ddraw->dest_window, NULL); if (cooplevel & DDSCL_FULLSCREEN) { @@ -1120,7 +1128,21 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW /* TODO: The possible return values from msdn suggest that the screen mode * can't be changed if a surface is locked or some drawing is in progress. */ if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode))) + { + if (ddraw->primary) + { + DDSURFACEDESC2 *surface_desc = &ddraw->primary->surface_desc; + + if (FAILED(hr = wined3d_swapchain_resize_buffers(ddraw->wined3d_swapchain, 0, + surface_desc->dwWidth, surface_desc->dwHeight, mode.format_id, WINED3D_MULTISAMPLE_NONE, 0))) + ERR("Failed to resize buffers, hr %#x.\n", hr); + else + ddrawformat_from_wined3dformat(&ddraw->primary->surface_desc.u4.ddpfPixelFormat, mode.format_id); + } ddraw->flags |= DDRAW_RESTORE_MODE; + } + + InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_OK); wined3d_mutex_unlock(); @@ -1487,7 +1509,7 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD hr = wined3d_device_get_device_caps(ddraw->wined3d_device, &winecaps); if (FAILED(hr)) { - WARN("IWineD3DDevice::GetDeviceCaps failed\n"); + WARN("Failed to get device caps, %#x.\n", hr); wined3d_mutex_unlock(); return hr; } @@ -1527,6 +1549,8 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD caps.dwCaps |= DDCAPS_ALIGNSTRIDE; caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT; + caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps; + IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps); if(DriverCaps) @@ -1627,7 +1651,7 @@ static HRESULT WINAPI ddraw1_Compact(IDirectDraw *iface) * * Returns information about the current display mode * - * Exists in Version 1, 2, 4 and 7 + * Exists in versions 1, 2, 4 and 7 * * Params: * DDSD: Address of a surface description structure to write the info to @@ -1718,7 +1742,7 @@ static HRESULT WINAPI ddraw1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *s * * Returns an array of supported FourCC codes. * - * Exists in Version 1, 2, 4 and 7 + * Exists in versions 1, 2, 4 and 7 * * Params: * NumCodes: Contains the number of Codes that Codes can carry. Returns the number @@ -1756,7 +1780,7 @@ static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); ++i) { if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_SURFACE, formats[i]))) + mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) { if (count < outsize) Codes[count] = formats[i]; @@ -1905,7 +1929,7 @@ static HRESULT WINAPI ddraw1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *st * Returns the total and free video memory * * Params: - * Caps: Specifies the memory type asked for + * caps: Specifies the memory type asked for * total: Pointer to a DWORD to be filled with the total memory * free: Pointer to a DWORD to be filled with the free memory * @@ -1914,18 +1938,23 @@ static HRESULT WINAPI ddraw1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *st * DDERR_INVALIDPARAMS if free and total are NULL * *****************************************************************************/ -static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, +static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *caps, DWORD *total, DWORD *free) { + unsigned int framebuffer_size, total_vidmem, free_vidmem; struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + struct wined3d_display_mode mode; HRESULT hr = DD_OK; - TRACE("iface %p, caps %p, total %p, free %p.\n", iface, Caps, total, free); + TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free); + + if (!total && !free) + return DDERR_INVALIDPARAMS; if (TRACE_ON(ddraw)) { TRACE("Asked for memory with description: "); - DDRAW_dump_DDSCAPS2(Caps); + DDRAW_dump_DDSCAPS2(caps); } wined3d_mutex_lock(); @@ -1934,20 +1963,34 @@ static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *C * resources, but that's not important */ - if( (!total) && (!free) ) + /* Some applications (e.g. 3DMark 2000) assume that the reported amount of + * video memory doesn't include the memory used by the default framebuffer. + */ + if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) { + WARN("Failed to get display mode, hr %#x.\n", hr); wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; + return hr; } + framebuffer_size = wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT, + mode.format_id, mode.width); + framebuffer_size *= mode.height; if (free) - *free = wined3d_device_get_available_texture_mem(ddraw->wined3d_device); + { + free_vidmem = wined3d_device_get_available_texture_mem(ddraw->wined3d_device); + *free = framebuffer_size > free_vidmem ? 0 : free_vidmem - framebuffer_size; + TRACE("Free video memory %#x.\n", *free); + } + if (total) { struct wined3d_adapter_identifier desc = {0}; hr = wined3d_get_adapter_identifier(ddraw->wined3d, WINED3DADAPTER_DEFAULT, 0, &desc); - *total = min(UINT_MAX, desc.video_memory); + total_vidmem = min(UINT_MAX, desc.video_memory); + *total = framebuffer_size > total_vidmem ? 0 : total_vidmem - framebuffer_size; + TRACE("Total video memory %#x.\n", *total); } wined3d_mutex_unlock(); @@ -2058,7 +2101,14 @@ static HRESULT WINAPI d3d1_Initialize(IDirect3D *iface, REFIID riid) *****************************************************************************/ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface) { - FIXME("iface %p stub!\n", iface); + struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + + TRACE("iface %p.\n", iface); + + ddraw->flags |= DDRAW_GDI_FLIP; + + if (ddraw->primary) + ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE); return DD_OK; } @@ -2797,6 +2847,18 @@ static HRESULT WINAPI ddraw7_CreateSurface(IDirectDraw7 *iface, DDSURFACEDESC2 * return DDERR_INVALIDPARAMS; } + __TRY + { + *surface = NULL; + } + __EXCEPT_PAGE_FAULT + { + WARN("Surface pointer %p is invalid.\n", surface); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + __ENDTRY; + if(surface_desc->ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)) { if (TRACE_ON(ddraw)) @@ -2813,10 +2875,7 @@ static HRESULT WINAPI ddraw7_CreateSurface(IDirectDraw7 *iface, DDSURFACEDESC2 * hr = ddraw_surface_create(ddraw, surface_desc, &impl, outer_unknown, 7); wined3d_mutex_unlock(); if (FAILED(hr)) - { - *surface = NULL; return hr; - } *surface = &impl->IDirectDrawSurface7_iface; IDirectDraw7_AddRef(iface); @@ -2851,6 +2910,18 @@ static HRESULT WINAPI ddraw4_CreateSurface(IDirectDraw4 *iface, return DDERR_INVALIDPARAMS; } + __TRY + { + *surface = NULL; + } + __EXCEPT_PAGE_FAULT + { + WARN("Surface pointer %p is invalid.\n", surface); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + __ENDTRY; + if(surface_desc->ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)) { if (TRACE_ON(ddraw)) @@ -2867,10 +2938,7 @@ static HRESULT WINAPI ddraw4_CreateSurface(IDirectDraw4 *iface, hr = ddraw_surface_create(ddraw, surface_desc, &impl, outer_unknown, 4); wined3d_mutex_unlock(); if (FAILED(hr)) - { - *surface = NULL; return hr; - } *surface = &impl->IDirectDrawSurface4_iface; IDirectDraw4_AddRef(iface); @@ -2906,6 +2974,18 @@ static HRESULT WINAPI ddraw2_CreateSurface(IDirectDraw2 *iface, return DDERR_INVALIDPARAMS; } + __TRY + { + *surface = NULL; + } + __EXCEPT_PAGE_FAULT + { + WARN("Surface pointer %p is invalid.\n", surface); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + __ENDTRY; + DDSD_to_DDSD2(surface_desc, &surface_desc2); if(surface_desc->ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)) { @@ -2923,10 +3003,7 @@ static HRESULT WINAPI ddraw2_CreateSurface(IDirectDraw2 *iface, hr = ddraw_surface_create(ddraw, &surface_desc2, &impl, outer_unknown, 2); wined3d_mutex_unlock(); if (FAILED(hr)) - { - *surface = NULL; return hr; - } *surface = &impl->IDirectDrawSurface_iface; impl->ifaceToRelease = NULL; @@ -2961,6 +3038,18 @@ static HRESULT WINAPI ddraw1_CreateSurface(IDirectDraw *iface, return DDERR_INVALIDPARAMS; } + __TRY + { + *surface = NULL; + } + __EXCEPT_PAGE_FAULT + { + WARN("Surface pointer %p is invalid.\n", surface); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + __ENDTRY; + if ((surface_desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)) == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER) || (surface_desc->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER)) @@ -2975,10 +3064,7 @@ static HRESULT WINAPI ddraw1_CreateSurface(IDirectDraw *iface, hr = ddraw_surface_create(ddraw, &surface_desc2, &impl, outer_unknown, 1); wined3d_mutex_unlock(); if (FAILED(hr)) - { - *surface = NULL; return hr; - } *surface = &impl->IDirectDrawSurface_iface; impl->ifaceToRelease = NULL; @@ -2986,9 +3072,6 @@ static HRESULT WINAPI ddraw1_CreateSurface(IDirectDraw *iface, return hr; } -#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST) -#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH) - static BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested, const DDPIXELFORMAT *provided) @@ -3095,9 +3178,6 @@ static BOOL ddraw_match_surface_desc(const DDSURFACEDESC2 *requested, const DDSU return TRUE; } -#undef DDENUMSURFACES_SEARCHTYPE -#undef DDENUMSURFACES_MATCHTYPE - struct surfacescallback2_context { LPDDENUMSURFACESCALLBACK2 func; @@ -3696,7 +3776,7 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA * Enumerates all supported Direct3DDevice interfaces. This is the * implementation for Direct3D 1 to Direc3D 3, Version 7 has its own. * - * Version 1, 2 and 3 + * Versions 1, 2 and 3 * * Params: * callback: Application-provided routine to call for each enumerated device @@ -3838,7 +3918,7 @@ static HRESULT WINAPI d3d1_EnumDevices(IDirect3D *iface, LPD3DENUMDEVICESCALLBAC * by the DIRECT3DLIGHT7 structure. Wine's Direct3DLight implementation * uses the IDirect3DDevice7 interface with D3D7 lights. * - * Version 1, 2 and 3 + * Versions 1, 2 and 3 * * Params: * light: Address to store the new interface pointer @@ -3901,7 +3981,7 @@ static HRESULT WINAPI d3d1_CreateLight(IDirect3D *iface, IDirect3DLight **light, * and older versions. The IDirect3DMaterial implementation wraps its * functionality to IDirect3DDevice7::SetMaterial and friends. * - * Version 1, 2 and 3 + * Versions 1, 2 and 3 * * Params: * material: Address to store the new interface's pointer to @@ -4050,7 +4130,7 @@ static HRESULT WINAPI d3d1_CreateViewport(IDirect3D *iface, IDirect3DViewport ** * This method finds a device with the requested properties and returns a * device description * - * Verion 1, 2 and 3 + * Versions 1, 2 and 3 * Params: * fds: Describes the requested device characteristics * fdr: Returns the device description @@ -4071,8 +4151,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd if (!fds || !fdr) return DDERR_INVALIDPARAMS; - if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) - || fdr->dwSize != sizeof(D3DFINDDEVICERESULT)) + if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) && + fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT))) return DDERR_INVALIDPARAMS; if ((fds->dwFlags & D3DFDS_COLORMODEL) @@ -4101,8 +4181,24 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd /* Now return our own GUID */ ddraw_d3dcaps1_from_7(&desc1, &desc7); fdr->guid = IID_D3DDEVICE_WineD3D; - fdr->ddHwDesc = desc1; - fdr->ddSwDesc = desc1; + + if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT1)) + { + D3DFINDDEVICERESULT1 *fdr1 = (D3DFINDDEVICERESULT1 *)fdr; + memcpy(&fdr1->ddHwDesc, &desc1, sizeof(fdr1->ddHwDesc)); + memcpy(&fdr1->ddSwDesc, &desc1, sizeof(fdr1->ddSwDesc)); + } + else if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT2)) + { + D3DFINDDEVICERESULT2 *fdr2 = (D3DFINDDEVICERESULT2 *)fdr; + memcpy(&fdr2->ddHwDesc, &desc1, sizeof(fdr2->ddHwDesc)); + memcpy(&fdr2->ddSwDesc, &desc1, sizeof(fdr2->ddSwDesc)); + } + else + { + fdr->ddHwDesc = desc1; + fdr->ddSwDesc = desc1; + } TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n"); @@ -4132,7 +4228,7 @@ static HRESULT WINAPI d3d1_FindDevice(IDirect3D *iface, D3DFINDDEVICESEARCH *fds * * Creates an IDirect3DDevice7 interface. * - * Version 2, 3 and 7. IDirect3DDevice 1 interfaces are interfaces to + * Versions 2, 3 and 7. IDirect3DDevice 1 interfaces are interfaces to * DirectDraw surfaces and are created with * IDirectDrawSurface::QueryInterface. This method uses CreateDevice to * create the device object and QueryInterfaces for IDirect3DDevice @@ -4234,7 +4330,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, * Creates a new vertex buffer object and returns a IDirect3DVertexBuffer7 * interface. * - * Version 3 and 7 + * Versions 3 and 7 * * Params: * desc: Requested Vertex buffer properties @@ -4244,7 +4340,6 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, * Returns * D3D_OK on success * DDERR_OUTOFMEMORY if memory allocation failed - * The return value of IWineD3DDevice::CreateVertexBuffer if this call fails * DDERR_INVALIDPARAMS if desc or vertex_buffer is NULL * *****************************************************************************/ @@ -4291,7 +4386,7 @@ static HRESULT WINAPI d3d3_CreateVertexBuffer(IDirect3D3 *iface, D3DVERTEXBUFFER if (hr == D3D_OK) { TRACE("Created vertex buffer %p.\n", object); - *vertex_buffer = &object->IDirect3DVertexBuffer_iface; + *vertex_buffer = (IDirect3DVertexBuffer *)&object->IDirect3DVertexBuffer7_iface; } else WARN("Failed to create vertex buffer, hr %#x.\n", hr); @@ -4304,7 +4399,7 @@ static HRESULT WINAPI d3d3_CreateVertexBuffer(IDirect3D3 *iface, D3DVERTEXBUFFER * * Enumerates all supported Z buffer pixel formats * - * Version 3 and 7 + * Versions 3 and 7 * * Params: * device_iid: @@ -4314,7 +4409,6 @@ static HRESULT WINAPI d3d3_CreateVertexBuffer(IDirect3D3 *iface, D3DVERTEXBUFFER * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if callback is NULL - * For details, see IWineD3DDevice::EnumZBufferFormats * *****************************************************************************/ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device_iid, @@ -4389,7 +4483,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i) { if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id, - WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_SURFACE, formats[i]))) + WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, formats[i]))) { DDPIXELFORMAT pformat; @@ -4413,7 +4507,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device * pixel format, so we use dwZBufferBitDepth=32. Some games expect 24. Windows Vista and * newer enumerate both versions, so we do the same(bug 22434) */ if (SUCCEEDED(wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, type, mode.format_id, - WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_SURFACE, WINED3DFMT_X8D24_UNORM))) + WINED3DUSAGE_DEPTHSTENCIL, WINED3D_RTYPE_TEXTURE_2D, WINED3DFMT_X8D24_UNORM))) { DDPIXELFORMAT x8d24 = { @@ -4448,7 +4542,7 @@ static HRESULT WINAPI d3d3_EnumZBufferFormats(IDirect3D3 *iface, REFCLSID device * Removes all managed textures (=surfaces with DDSCAPS2_TEXTUREMANAGE or * DDSCAPS2_D3DTEXTUREMANAGE caps) to be removed from video memory. * - * Version 3 and 7 + * Versions 3 and 7 * * Returns: * D3D_OK, because it's a stub @@ -4889,13 +4983,14 @@ static const struct wined3d_parent_ops ddraw_frontbuffer_parent_ops = }; static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, - void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture) + void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, + struct wined3d_texture **texture) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); HRESULT hr; - TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n", - device_parent, container_parent, desc, texture); + TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", + device_parent, container_parent, desc, texture_flags, texture); if (ddraw->wined3d_frontbuffer) { @@ -4903,8 +4998,8 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return E_FAIL; } - if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, - WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1, + texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/reactos/dll/directx/wine/ddraw/ddraw.spec b/reactos/dll/directx/wine/ddraw/ddraw.spec index 75750910e48..a6cf1411703 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.spec +++ b/reactos/dll/directx/wine/ddraw/ddraw.spec @@ -15,7 +15,7 @@ @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() @ stub GetNextMipMap -@ stub GetSurfaceFromDC +@ stdcall GetSurfaceFromDC(ptr ptr ptr) @ stub HeapVidMemAllocAligned @ stub InternalLock @ stub InternalUnlock diff --git a/reactos/dll/directx/wine/ddraw/ddraw_private.h b/reactos/dll/directx/wine/ddraw/ddraw_private.h index 3fafacdafd8..948b0f21a13 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_private.h +++ b/reactos/dll/directx/wine/ddraw/ddraw_private.h @@ -62,11 +62,14 @@ struct FvfToDecl #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_RECURSIVE 0x00000020 +#define DDRAW_GDI_FLIP 0x00000040 #define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ - | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER) + | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \ + | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ + | WINED3D_LEGACY_CUBEMAP_FILTERING) enum ddraw_device_state { @@ -131,7 +134,6 @@ struct ddraw HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type device_type) DECLSPEC_HIDDEN; void ddraw_d3dcaps1_from_7(D3DDEVICEDESC *caps1, D3DDEVICEDESC7 *caps7) DECLSPEC_HIDDEN; -void ddraw_destroy_swapchain(struct ddraw *ddraw) DECLSPEC_HIDDEN; HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) DECLSPEC_HIDDEN; void ddraw_update_lost_surfaces(struct ddraw *ddraw) DECLSPEC_HIDDEN; @@ -185,7 +187,7 @@ struct ddraw_surface */ #define MAX_COMPLEX_ATTACHED 6 struct ddraw_surface *complex_array[MAX_COMPLEX_ATTACHED]; - /* You can't traverse the tree upwards. Only a flag for Surface::Release because its needed there, + /* You can't traverse the tree upwards. Only a flag for Surface::Release because it's needed there, * but no pointer to prevent temptations to traverse it in the wrong direction. */ BOOL is_complex_root; @@ -211,6 +213,7 @@ struct ddraw_texture DDSURFACEDESC2 surface_desc; struct ddraw_surface *root; + struct wined3d_device *wined3d_device; }; HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, @@ -219,7 +222,6 @@ struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddr void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; -ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) DECLSPEC_HIDDEN; @@ -402,7 +404,7 @@ struct ddraw_palette IDirectDrawPalette IDirectDrawPalette_iface; LONG ref; - struct wined3d_palette *wineD3DPalette; + struct wined3d_palette *wined3d_palette; struct ddraw *ddraw; IUnknown *ifaceToRelease; DWORD flags; @@ -529,10 +531,9 @@ struct d3d_execute_buffer D3DEXECUTEDATA data; /* This buffer will store the transformed vertices */ - void *vertex_data; - WORD *indices; - unsigned int nb_indices; - unsigned int nb_vertices; + unsigned int index_size, index_pos; + unsigned int vertex_size, src_vertex_pos; + struct wined3d_buffer *src_vertex_buffer, *dst_vertex_buffer, *index_buffer; /* This flags is set to TRUE if we allocated ourselves the * data buffer @@ -554,12 +555,12 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *execute_buffer, struct d3d_vertex_buffer { IDirect3DVertexBuffer7 IDirect3DVertexBuffer7_iface; - IDirect3DVertexBuffer IDirect3DVertexBuffer_iface; LONG ref; + unsigned int version; /*** WineD3D and ddraw links ***/ - struct wined3d_buffer *wineD3DVertexBuffer; - struct wined3d_vertex_declaration *wineD3DVertexDeclaration; + struct wined3d_buffer *wined3d_buffer; + struct wined3d_vertex_declaration *wined3d_declaration; struct ddraw *ddraw; /*** Storage for D3D7 specific things ***/ @@ -586,6 +587,8 @@ struct d3d_vertex_buffer *unsafe_impl_from_IDirect3DVertexBuffer7(IDirect3DVerte void ddrawformat_from_wined3dformat(DDPIXELFORMAT *ddraw_format, enum wined3d_format_id wined3d_format) DECLSPEC_HIDDEN; +BOOL wined3d_colour_from_ddraw_colour(const DDPIXELFORMAT *pf, const struct ddraw_palette *palette, + DWORD colour, struct wined3d_color *wined3d_colour) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *format) DECLSPEC_HIDDEN; void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) DECLSPEC_HIDDEN; void dump_D3DMATRIX(const D3DMATRIX *mat) DECLSPEC_HIDDEN; @@ -632,10 +635,10 @@ struct member_info /* Structure copy */ #define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) } -#define DD_STRUCT_COPY_BYSIZE_(to,from,from_size) \ +#define DD_STRUCT_COPY_BYSIZE_(to,from,to_size,from_size) \ do { \ DWORD __size = (to)->dwSize; \ - DWORD __resetsize = min(__size, sizeof(*to)); \ + DWORD __resetsize = min(to_size, sizeof(*to)); \ DWORD __copysize = min(__resetsize, from_size); \ assert(to != from); \ memcpy(to, from, __copysize); \ @@ -643,7 +646,7 @@ struct member_info (to)->dwSize = __size; /* restore size */ \ } while (0) -#define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(from)->dwSize) +#define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(to)->dwSize,(from)->dwSize) HRESULT hr_ddraw_from_wined3d(HRESULT hr) DECLSPEC_HIDDEN; diff --git a/reactos/dll/directx/wine/ddraw/device.c b/reactos/dll/directx/wine/ddraw/device.c index c90a0448ba5..6b93266467e 100644 --- a/reactos/dll/directx/wine/ddraw/device.c +++ b/reactos/dll/directx/wine/ddraw/device.c @@ -1015,9 +1015,8 @@ static HRESULT WINAPI d3d_device1_GetPickRecords(IDirect3DDevice *iface, /***************************************************************************** * IDirect3DDevice7::EnumTextureformats * - * Enumerates the supported texture formats. It has a list of all possible - * formats and calls IWineD3D::CheckDeviceFormat for each format to see if - * WineD3D supports it. If so, then it is passed to the app. + * Enumerates the supported texture formats. It checks against a list of all possible + * formats to see if WineD3D supports it. If so, then it is passed to the app. * * This is for Version 7 and 3, older versions have a different * callback function and their own implementation @@ -1087,7 +1086,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) + mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1109,7 +1108,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface, for (i = 0; i < sizeof(BumpFormatList) / sizeof(*BumpFormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_QUERY_LEGACYBUMPMAP, + WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_LEGACYBUMPMAP, WINED3D_RTYPE_TEXTURE_2D, BumpFormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1215,7 +1214,7 @@ static HRESULT WINAPI d3d_device2_EnumTextureFormats(IDirect3DDevice2 *iface, for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) + mode.format_id, WINED3DUSAGE_TEXTURE, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDSURFACEDESC sdesc; @@ -1457,7 +1456,7 @@ static HRESULT WINAPI d3d_device1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIX * Version 1, 2, 3 and 7 * * Returns: - * D3D_OK on success, for details see IWineD3DDevice::BeginScene + * D3D_OK on success, * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already * started scene). * @@ -1530,7 +1529,7 @@ static HRESULT WINAPI d3d_device1_BeginScene(IDirect3DDevice *iface) * Version 1, 2, 3 and 7 * * Returns: - * D3D_OK on success, for details see IWineD3DDevice::EndScene + * D3D_OK on success, * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does * that only if the scene was already ended. * @@ -2280,7 +2279,7 @@ static HRESULT WINAPI d3d_device2_Index(IDirect3DDevice2 *iface, WORD index) * Value: Address to store the value at * * Returns: - * D3D_OK on success, for details see IWineD3DDevice::GetRenderState + * D3D_OK on success, * DDERR_INVALIDPARAMS if Value == NULL * *****************************************************************************/ @@ -2496,17 +2495,13 @@ static HRESULT WINAPI d3d_device3_GetRenderState(IDirect3DDevice3 *iface, if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) { - struct wined3d_resource *sub_resource; + struct wined3d_resource_desc desc; - if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) - { - struct wined3d_resource_desc desc; - - wined3d_resource_get_desc(sub_resource, &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; - } + wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); + ddfmt.dwSize = sizeof(ddfmt); + ddrawformat_from_wined3dformat(&ddfmt, desc.format); + if (ddfmt.u5.dwRGBAlphaBitMask) + tex_alpha = TRUE; } if (!(colorop == WINED3D_TOP_MODULATE @@ -2556,10 +2551,6 @@ static HRESULT WINAPI d3d_device2_GetRenderState(IDirect3DDevice2 *iface, * RenderStateType: State to set * Value: Value to assign to that state * - * Returns: - * D3D_OK on success, - * for details see IWineD3DDevice::SetRenderState - * *****************************************************************************/ static HRESULT d3d_device7_SetRenderState(IDirect3DDevice7 *iface, D3DRENDERSTATETYPE state, DWORD value) @@ -2797,17 +2788,13 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) { - struct wined3d_resource *sub_resource; + struct wined3d_resource_desc desc; - if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) - { - struct wined3d_resource_desc desc; - - wined3d_resource_get_desc(sub_resource, &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; - } + wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); + ddfmt.dwSize = sizeof(ddfmt); + ddrawformat_from_wined3dformat(&ddfmt, desc.format); + if (ddfmt.u5.dwRGBAlphaBitMask) + tex_alpha = TRUE; } if (tex_alpha) @@ -3141,7 +3128,6 @@ static HRESULT WINAPI d3d_device2_GetLightState(IDirect3DDevice2 *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Matrix == NULL - * For details see IWineD3DDevice::SetTransform * *****************************************************************************/ static HRESULT d3d_device7_SetTransform(IDirect3DDevice7 *iface, @@ -3234,7 +3220,7 @@ static HRESULT WINAPI d3d_device2_SetTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_SetTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_SetTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** @@ -3251,7 +3237,6 @@ static HRESULT WINAPI d3d_device2_SetTransform(IDirect3DDevice2 *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Matrix == NULL - * For details, see IWineD3DDevice::GetTransform * *****************************************************************************/ static HRESULT d3d_device7_GetTransform(IDirect3DDevice7 *iface, @@ -3338,7 +3323,7 @@ static HRESULT WINAPI d3d_device2_GetTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_GetTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_GetTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** @@ -3356,7 +3341,6 @@ static HRESULT WINAPI d3d_device2_GetTransform(IDirect3DDevice2 *iface, * Returns * D3D_OK on success * DDERR_INVALIDPARAMS if D3DMatrix is NULL - * For details, see IWineD3DDevice::MultiplyTransform * *****************************************************************************/ static HRESULT d3d_device7_MultiplyTransform(IDirect3DDevice7 *iface, @@ -3445,7 +3429,7 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_MultiplyTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_MultiplyTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** @@ -3466,7 +3450,6 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Vertices is NULL - * For details, see IWineD3DDevice::DrawPrimitiveUP * *****************************************************************************/ @@ -3505,15 +3488,20 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, DWORD vertex_count, DWORD flags) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; UINT stride, vb_pos, size, align; + struct wined3d_resource *vb; HRESULT hr; - BYTE *data; TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n", iface, primitive_type, fvf, vertices, vertex_count, flags); - if (!vertices) - return DDERR_INVALIDPARAMS; + if (!vertex_count) + { + WARN("0 vertex count.\n"); + return D3D_OK; + } /* Get the stride */ stride = get_flexible_vertex_size(fvf); @@ -3532,12 +3520,14 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(data, vertices, size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, vertices, size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); @@ -3545,7 +3535,7 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, goto done; wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf)); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vertex_count); done: @@ -3646,7 +3636,6 @@ static HRESULT WINAPI d3d_device2_DrawPrimitive(IDirect3DDevice2 *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Vertices or Indices is NULL - * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP * *****************************************************************************/ /* The caller is responsible for wined3d locking */ @@ -3686,13 +3675,21 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, HRESULT hr; UINT stride = get_flexible_vertex_size(fvf); UINT vtx_size = stride * vertex_count, idx_size = index_count * sizeof(*indices); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *ib, *vb; UINT vb_pos, ib_pos, align; - BYTE *data; TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, " "indices %p, index_count %u, flags %#x.\n", iface, primitive_type, fvf, vertices, vertex_count, indices, index_count, flags); + if (!vertex_count || !index_count) + { + WARN("0 vertex or index count.\n"); + return D3D_OK; + } + /* Set the D3DDevice's FVF */ wined3d_mutex_lock(); @@ -3708,12 +3705,14 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + vtx_size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(data, vertices, vtx_size); - wined3d_buffer_unmap(device->vertex_buffer); + memcpy(wined3d_map_desc.data, vertices, vtx_size); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + vtx_size; hr = d3d_device_prepare_index_buffer(device, idx_size); @@ -3723,21 +3722,23 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, if (device->index_buffer_size - idx_size < ib_pos) ib_pos = 0; - hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &data, - ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = ib_pos; + wined3d_box.right = ib_pos + idx_size; + ib = wined3d_buffer_get_resource(device->index_buffer); + if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, + ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(data, indices, idx_size); - wined3d_buffer_unmap(device->index_buffer); + memcpy(wined3d_map_desc.data, indices, idx_size); + wined3d_resource_unmap(ib, 0); device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); if (FAILED(hr)) goto done; - wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT); + wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT, 0); wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf)); - wined3d_device_set_primitive_type(device->wined3d_device, primitive_type); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / stride); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count); @@ -3867,10 +3868,6 @@ static HRESULT WINAPI d3d_device7_SetClipStatus(IDirect3DDevice7 *iface, D3DCLIP { FIXME("iface %p, clip_status %p stub!\n", iface, clip_status); - /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them - * Perhaps this needs a new data type and an additional IWineD3DDevice method - */ - /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/ return D3D_OK; } @@ -3908,8 +3905,6 @@ static HRESULT WINAPI d3d_device7_GetClipStatus(IDirect3DDevice7 *iface, D3DCLIP { FIXME("iface %p, clip_status %p stub!\n", iface, clip_status); - /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */ - /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/ return D3D_OK; } @@ -3949,7 +3944,6 @@ static HRESULT WINAPI d3d_device2_GetClipStatus(IDirect3DDevice2 *iface, D3DCLIP * Returns: * D3D_OK, because it's a stub * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) - * (For details, see IWineD3DDevice::DrawPrimitiveStrided) * *****************************************************************************/ static void pack_strided_data(BYTE *dst, DWORD count, const D3DDRAWPRIMITIVESTRIDEDDATA *src, DWORD fvf) @@ -4008,18 +4002,26 @@ static void pack_strided_data(BYTE *dst, DWORD count, const D3DDRAWPRIMITIVESTRI } } -static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE PrimitiveType, - DWORD VertexType, D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags) +static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE primitive_type, + DWORD fvf, D3DDRAWPRIMITIVESTRIDEDDATA *strided_data, DWORD vertex_count, DWORD flags) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); HRESULT hr; - UINT dst_stride = get_flexible_vertex_size(VertexType); - UINT dst_size = dst_stride * VertexCount; + UINT dst_stride = get_flexible_vertex_size(fvf); + UINT dst_size = dst_stride * vertex_count; + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *vb; UINT vb_pos, align; - BYTE *dst_data; - TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n", - iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); + TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, vertex_count %u, flags %#x.\n", + iface, primitive_type, fvf, strided_data, vertex_count, flags); + + if (!vertex_count) + { + WARN("0 vertex count.\n"); + return D3D_OK; + } wined3d_mutex_lock(); hr = d3d_device_prepare_vertex_buffer(device, dst_size); @@ -4034,21 +4036,23 @@ static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIM else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, dst_size, &dst_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + dst_size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - pack_strided_data(dst_data, VertexCount, D3DDrawPrimStrideData, VertexType); - wined3d_buffer_unmap(device->vertex_buffer); + pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + dst_size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, dst_stride); if (FAILED(hr)) goto done; - wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, VertexType)); + wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf)); - wined3d_device_set_primitive_type(device->wined3d_device, PrimitiveType); - hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, VertexCount); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); + hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, vertex_count); done: wined3d_mutex_unlock(); @@ -4107,25 +4111,32 @@ static HRESULT WINAPI d3d_device3_DrawPrimitiveStrided(IDirect3DDevice3 *iface, * D3D_OK, because it's a stub * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) * (DDERR_INVALIDPARAMS if Indices is NULL) - * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided) * *****************************************************************************/ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, - D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, - D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, - WORD *Indices, DWORD IndexCount, DWORD Flags) + D3DPRIMITIVETYPE primitive_type, DWORD fvf, D3DDRAWPRIMITIVESTRIDEDDATA *strided_data, + DWORD vertex_count, WORD *indices, DWORD index_count, DWORD flags) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); - HRESULT hr; - UINT vtx_dst_stride = get_flexible_vertex_size(VertexType); - UINT vtx_dst_size = VertexCount * vtx_dst_stride; + UINT vtx_dst_stride = get_flexible_vertex_size(fvf); + UINT vtx_dst_size = vertex_count * vtx_dst_stride; + UINT idx_size = index_count * sizeof(WORD); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *ib, *vb; UINT vb_pos, align; - UINT idx_size = IndexCount * sizeof(WORD); UINT ib_pos; - BYTE *dst_data; + HRESULT hr; - TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", - iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); + TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, " + "vertex_count %u, indices %p, index_count %u, flags %#x.\n", + iface, primitive_type, fvf, strided_data, vertex_count, indices, index_count, flags); + + if (!vertex_count || !index_count) + { + WARN("0 vertex or index count.\n"); + return D3D_OK; + } wined3d_mutex_lock(); @@ -4141,12 +4152,14 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, else vb_pos += align; - hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_dst_size, &dst_data, - vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = vb_pos; + wined3d_box.right = vb_pos + vtx_dst_size; + vb = wined3d_buffer_get_resource(device->vertex_buffer); + if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, + vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - pack_strided_data(dst_data, VertexCount, D3DDrawPrimStrideData, VertexType); - wined3d_buffer_unmap(device->vertex_buffer); + pack_strided_data(wined3d_map_desc.data, vertex_count, strided_data, fvf); + wined3d_resource_unmap(vb, 0); device->vertex_buffer_pos = vb_pos + vtx_dst_size; hr = d3d_device_prepare_index_buffer(device, idx_size); @@ -4156,23 +4169,25 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, if (device->index_buffer_size - idx_size < ib_pos) ib_pos = 0; - hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &dst_data, - ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + wined3d_box.left = ib_pos; + wined3d_box.right = ib_pos + idx_size; + ib = wined3d_buffer_get_resource(device->index_buffer); + if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, + ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) goto done; - memcpy(dst_data, Indices, idx_size); - wined3d_buffer_unmap(device->index_buffer); + memcpy(wined3d_map_desc.data, indices, idx_size); + wined3d_resource_unmap(ib, 0); device->index_buffer_pos = ib_pos + idx_size; hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vtx_dst_stride); if (FAILED(hr)) goto done; - wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT); + wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vtx_dst_stride); - wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, VertexType)); - wined3d_device_set_primitive_type(device->wined3d_device, PrimitiveType); - hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), IndexCount); + wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, fvf)); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); + hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count); done: wined3d_mutex_unlock(); @@ -4239,29 +4254,29 @@ static HRESULT WINAPI d3d_device3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 * * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL * *****************************************************************************/ -static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE PrimitiveType, - IDirect3DVertexBuffer7 *D3DVertexBuf, DWORD StartVertex, DWORD NumVertices, DWORD Flags) +static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE primitive_type, + IDirect3DVertexBuffer7 *vb, DWORD start_vertex, DWORD vertex_count, DWORD flags) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); - struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf); + struct d3d_vertex_buffer *vb_impl = unsafe_impl_from_IDirect3DVertexBuffer7(vb); HRESULT hr; DWORD stride; TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n", - iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); + iface, primitive_type, vb, start_vertex, vertex_count, flags); - /* Sanity checks */ - if (!vb) + if (!vertex_count) { - WARN("No Vertex buffer specified.\n"); - return DDERR_INVALIDPARAMS; + WARN("0 vertex count.\n"); + return D3D_OK; } - stride = get_flexible_vertex_size(vb->fvf); + + stride = get_flexible_vertex_size(vb_impl->fvf); wined3d_mutex_lock(); - wined3d_device_set_vertex_declaration(device->wined3d_device, vb->wineD3DVertexDeclaration); - hr = wined3d_device_set_stream_source(device->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride); - if (FAILED(hr)) + wined3d_device_set_vertex_declaration(device->wined3d_device, vb_impl->wined3d_declaration); + if (FAILED(hr = wined3d_device_set_stream_source(device->wined3d_device, + 0, vb_impl->wined3d_buffer, 0, stride))) { WARN("Failed to set stream source, hr %#x.\n", hr); wined3d_mutex_unlock(); @@ -4269,8 +4284,8 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE } /* Now draw the primitives */ - wined3d_device_set_primitive_type(device->wined3d_device, PrimitiveType); - hr = wined3d_device_draw_primitive(device->wined3d_device, StartVertex, NumVertices); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); + hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count); wined3d_mutex_unlock(); @@ -4300,7 +4315,7 @@ static HRESULT WINAPI d3d_device3_DrawPrimitiveVB(IDirect3DDevice3 *iface, D3DPR IDirect3DVertexBuffer *D3DVertexBuf, DWORD StartVertex, DWORD NumVertices, DWORD Flags) { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf); + struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7 *)D3DVertexBuf); TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n", iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); @@ -4329,73 +4344,80 @@ static HRESULT WINAPI d3d_device3_DrawPrimitiveVB(IDirect3DDevice3 *iface, D3DPR * *****************************************************************************/ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, - D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer7 *D3DVertexBuf, - DWORD StartVertex, DWORD NumVertices, WORD *Indices, DWORD IndexCount, DWORD Flags) + D3DPRIMITIVETYPE primitive_type, IDirect3DVertexBuffer7 *vb, + DWORD start_vertex, DWORD vertex_count, WORD *indices, DWORD index_count, DWORD flags) { - struct d3d_device *This = impl_from_IDirect3DDevice7(iface); - struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf); - DWORD stride = get_flexible_vertex_size(vb->fvf); - WORD *LockedIndices; + struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct d3d_vertex_buffer *vb_impl = unsafe_impl_from_IDirect3DVertexBuffer7(vb); + DWORD stride = get_flexible_vertex_size(vb_impl->fvf); + struct wined3d_map_desc wined3d_map_desc; + struct wined3d_box wined3d_box = {0}; + struct wined3d_resource *ib; HRESULT hr; UINT ib_pos; - TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n", - iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags); + TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, " + "vertex_count %u, indices %p, index_count %u, flags %#x.\n", + iface, primitive_type, vb, start_vertex, vertex_count, indices, index_count, flags); + + if (!vertex_count || !index_count) + { + WARN("0 vertex or index count.\n"); + return D3D_OK; + } /* Steps: - * 1) Upload the Indices to the index buffer + * 1) Upload the indices to the index buffer * 2) Set the index source * 3) Set the Vertex Buffer as the Stream source - * 4) Call IWineD3DDevice::DrawIndexedPrimitive + * 4) Call wined3d_device_draw_indexed_primitive() */ wined3d_mutex_lock(); - wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration); + wined3d_device_set_vertex_declaration(device->wined3d_device, vb_impl->wined3d_declaration); - hr = d3d_device_prepare_index_buffer(This, IndexCount * sizeof(WORD)); + hr = d3d_device_prepare_index_buffer(device, index_count * sizeof(WORD)); if (FAILED(hr)) { wined3d_mutex_unlock(); return hr; } - ib_pos = This->index_buffer_pos; + ib_pos = device->index_buffer_pos; - if (This->index_buffer_size - IndexCount * sizeof(WORD) < ib_pos) + if (device->index_buffer_size - index_count * sizeof(WORD) < ib_pos) ib_pos = 0; - /* Copy the index stream into the index buffer. A new IWineD3DDevice - * method could be created which takes an user pointer containing the - * indices or a SetData-Method for the index buffer, which overrides the - * index buffer data with our pointer. */ - hr = wined3d_buffer_map(This->index_buffer, ib_pos, IndexCount * sizeof(WORD), - (BYTE **)&LockedIndices, ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); - if (FAILED(hr)) + /* Copy the index stream into the index buffer. */ + wined3d_box.left = ib_pos; + wined3d_box.right = ib_pos + index_count * sizeof(WORD); + ib = wined3d_buffer_get_resource(device->index_buffer); + if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, + ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) { ERR("Failed to map buffer, hr %#x.\n", hr); wined3d_mutex_unlock(); return hr; } - memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD)); - wined3d_buffer_unmap(This->index_buffer); - This->index_buffer_pos = ib_pos + IndexCount * sizeof(WORD); + memcpy(wined3d_map_desc.data, indices, index_count * sizeof(WORD)); + wined3d_resource_unmap(ib, 0); + device->index_buffer_pos = ib_pos + index_count * sizeof(WORD); /* Set the index stream */ - wined3d_device_set_base_vertex_index(This->wined3d_device, StartVertex); - wined3d_device_set_index_buffer(This->wined3d_device, This->index_buffer, WINED3DFMT_R16_UINT); + wined3d_device_set_base_vertex_index(device->wined3d_device, start_vertex); + wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, WINED3DFMT_R16_UINT, 0); /* Set the vertex stream source */ - hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_set_stream_source(device->wined3d_device, + 0, vb_impl->wined3d_buffer, 0, stride))) { - ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr); + ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", device, hr); wined3d_mutex_unlock(); return hr; } - - wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); - hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, ib_pos / sizeof(WORD), IndexCount); + wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); + hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count); wined3d_mutex_unlock(); @@ -4430,7 +4452,7 @@ static HRESULT WINAPI d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface DWORD IndexCount, DWORD Flags) { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); - struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf); + struct d3d_vertex_buffer *vb = unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7 *)D3DVertexBuf); TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n", iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags); @@ -4468,96 +4490,163 @@ static HRESULT WINAPI d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface * *****************************************************************************/ -static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius) +static DWORD in_plane(UINT idx, struct wined3d_vec4 p, D3DVECTOR center, D3DVALUE radius, BOOL equality) { float distance, norm; - norm = sqrtf(normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z); - distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm; + norm = sqrtf(p.x * p.x + p.y * p.y + p.z * p.z); + distance = (p.x * center.u1.x + p.y * center.u2.y + p.z * center.u3.z + p.w) / norm; - if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane; - if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane; + if (equality) + { + if (fabs(distance) <= radius) + return D3DSTATUS_CLIPUNIONLEFT << idx; + if (distance <= -radius) + return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << idx; + } + else + { + if (fabs(distance) < radius) + return D3DSTATUS_CLIPUNIONLEFT << idx; + if (distance < -radius) + return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << idx; + } return 0; } +static void prepare_clip_space_planes(struct d3d_device *device, struct wined3d_vec4 *plane) +{ + D3DMATRIX m, temp; + + /* We want the wined3d matrices since those include the legacy viewport + * transformation. */ + wined3d_mutex_lock(); + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_WORLD, (struct wined3d_matrix *)&m); + + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_VIEW, (struct wined3d_matrix *)&temp); + multiply_matrix(&m, &temp, &m); + + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&temp); + multiply_matrix(&m, &temp, &m); + wined3d_mutex_unlock(); + + /* Left plane. */ + plane[0].x = m._14 + m._11; + plane[0].y = m._24 + m._21; + plane[0].z = m._34 + m._31; + plane[0].w = m._44 + m._41; + + /* Right plane. */ + plane[1].x = m._14 - m._11; + plane[1].y = m._24 - m._21; + plane[1].z = m._34 - m._31; + plane[1].w = m._44 - m._41; + + /* Top plane. */ + plane[2].x = m._14 - m._12; + plane[2].y = m._24 - m._22; + plane[2].z = m._34 - m._32; + plane[2].w = m._44 - m._42; + + /* Bottom plane. */ + plane[3].x = m._14 + m._12; + plane[3].y = m._24 + m._22; + plane[3].z = m._34 + m._32; + plane[3].w = m._44 + m._42; + + /* Front plane. */ + plane[4].x = m._13; + plane[4].y = m._23; + plane[4].z = m._33; + plane[4].w = m._43; + + /* Back plane. */ + plane[5].x = m._14 - m._13; + plane[5].y = m._24 - m._23; + plane[5].z = m._34 - m._33; + plane[5].w = m._44 - m._43; +} + +static void compute_sphere_visibility(struct wined3d_vec4 plane[12], DWORD enabled_planes, BOOL equality, + D3DVECTOR *centers, D3DVALUE *radii, DWORD sphere_count, DWORD *return_values) +{ + UINT i, j; + + for (i = 0; i < sphere_count; ++i) + { + return_values[i] = 0; + for (j = 0; j < 12; ++j) + if (enabled_planes & 1u << j) + return_values[i] |= in_plane(j, plane[j], centers[i], radii[i], equality); + } +} + static HRESULT WINAPI d3d_device7_ComputeSphereVisibility(IDirect3DDevice7 *iface, D3DVECTOR *centers, D3DVALUE *radii, DWORD sphere_count, DWORD flags, DWORD *return_values) { - D3DMATRIX m, temp; - D3DVALUE origin_plane[6]; - D3DVECTOR vec[6]; - HRESULT hr; - UINT i, j; + struct wined3d_vec4 plane[12]; + DWORD enabled_planes = 0x3f; + DWORD user_clip_planes; + UINT j; TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n", iface, centers, radii, sphere_count, flags, return_values); - hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m); - if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; - hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp); - if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; - multiply_matrix(&m, &temp, &m); + prepare_clip_space_planes(impl_from_IDirect3DDevice7(iface), plane); - hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp); - if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; - multiply_matrix(&m, &temp, &m); - -/* Left plane */ - vec[0].u1.x = m._14 + m._11; - vec[0].u2.y = m._24 + m._21; - vec[0].u3.z = m._34 + m._31; - origin_plane[0] = m._44 + m._41; - -/* Right plane */ - vec[1].u1.x = m._14 - m._11; - vec[1].u2.y = m._24 - m._21; - vec[1].u3.z = m._34 - m._31; - origin_plane[1] = m._44 - m._41; - -/* Top plane */ - vec[2].u1.x = m._14 - m._12; - vec[2].u2.y = m._24 - m._22; - vec[2].u3.z = m._34 - m._32; - origin_plane[2] = m._44 - m._42; - -/* Bottom plane */ - vec[3].u1.x = m._14 + m._12; - vec[3].u2.y = m._24 + m._22; - vec[3].u3.z = m._34 + m._32; - origin_plane[3] = m._44 + m._42; - -/* Front plane */ - vec[4].u1.x = m._13; - vec[4].u2.y = m._23; - vec[4].u3.z = m._33; - origin_plane[4] = m._43; - -/* Back plane*/ - vec[5].u1.x = m._14 - m._13; - vec[5].u2.y = m._24 - m._23; - vec[5].u3.z = m._34 - m._33; - origin_plane[5] = m._44 - m._43; - - for (i = 0; i < sphere_count; ++i) - { - return_values[i] = 0; - for (j = 0; j < 6; ++j) - return_values[i] |= in_plane(j, vec[j], origin_plane[j], centers[i], radii[i]); - } + IDirect3DDevice7_GetRenderState(iface, D3DRENDERSTATE_CLIPPLANEENABLE, &user_clip_planes); + enabled_planes |= user_clip_planes << 6; + for (j = 6; j < 12; ++j) + IDirect3DDevice7_GetClipPlane(iface, j - 6, (D3DVALUE *)&plane[j]); + compute_sphere_visibility(plane, enabled_planes, FALSE, centers, radii, sphere_count, return_values); return D3D_OK; } static HRESULT WINAPI d3d_device3_ComputeSphereVisibility(IDirect3DDevice3 *iface, D3DVECTOR *centers, D3DVALUE *radii, DWORD sphere_count, DWORD flags, DWORD *return_values) { - struct d3d_device *device = impl_from_IDirect3DDevice3(iface); + static const DWORD enabled_planes = 0x3f; + struct wined3d_vec4 plane[6]; + unsigned int i, j; TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n", iface, centers, radii, sphere_count, flags, return_values); - return IDirect3DDevice7_ComputeSphereVisibility(&device->IDirect3DDevice7_iface, - centers, radii, sphere_count, flags, return_values); + prepare_clip_space_planes(impl_from_IDirect3DDevice3(iface), plane); + + compute_sphere_visibility(plane, enabled_planes, TRUE, centers, radii, sphere_count, return_values); + for (i = 0; i < sphere_count; ++i) + { + BOOL intersect_frustum = FALSE, outside_frustum = FALSE; + DWORD d3d7_result = return_values[i]; + + return_values[i] = 0; + + for (j = 0; j < 6; ++j) + { + DWORD clip = (d3d7_result >> j) & (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT); + + if (clip == D3DSTATUS_CLIPUNIONLEFT) + { + return_values[i] |= D3DVIS_INTERSECT_LEFT << j * 2; + intersect_frustum = TRUE; + } + else if (clip) + { + return_values[i] |= D3DVIS_OUTSIDE_LEFT << j * 2; + outside_frustum = TRUE; + } + } + if (outside_frustum) + return_values[i] |= D3DVIS_OUTSIDE_FRUSTUM; + else if (intersect_frustum) + return_values[i] |= D3DVIS_INTERSECT_FRUSTUM; + } + return D3D_OK; } /***************************************************************************** @@ -4576,7 +4665,6 @@ static HRESULT WINAPI d3d_device3_ComputeSphereVisibility(IDirect3DDevice3 *ifac * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Texture is NULL - * For details, see IWineD3DDevice::GetTexture * *****************************************************************************/ static HRESULT d3d_device7_GetTexture(IDirect3DDevice7 *iface, @@ -4658,7 +4746,6 @@ static HRESULT WINAPI d3d_device3_GetTexture(IDirect3DDevice3 *iface, DWORD stag * * Returns * D3D_OK on success - * For details, see IWineD3DDevice::SetTexture * *****************************************************************************/ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface, @@ -4727,17 +4814,13 @@ static HRESULT WINAPI d3d_device3_SetTexture(IDirect3DDevice3 *iface, if ((tex = wined3d_device_get_texture(device->wined3d_device, 0))) { - struct wined3d_resource *sub_resource; + struct wined3d_resource_desc desc; - if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) - { - struct wined3d_resource_desc desc; - - wined3d_resource_get_desc(sub_resource, &desc); - ddfmt.dwSize = sizeof(ddfmt); - ddrawformat_from_wined3dformat(&ddfmt, desc.format); - if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; - } + wined3d_resource_get_desc(wined3d_texture_get_resource(tex), &desc); + ddfmt.dwSize = sizeof(ddfmt); + ddrawformat_from_wined3dformat(&ddfmt, desc.format); + if (ddfmt.u5.dwRGBAlphaBitMask) + tex_alpha = TRUE; } /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */ @@ -4757,35 +4840,39 @@ static HRESULT WINAPI d3d_device3_SetTexture(IDirect3DDevice3 *iface, static const struct tss_lookup { BOOL sampler_state; - enum wined3d_texture_stage_state state; + union + { + enum wined3d_texture_stage_state texture_state; + enum wined3d_sampler_state sampler_state; + } u; } tss_lookup[] = { - {FALSE, WINED3D_TSS_INVALID}, /* 0, unused */ - {FALSE, WINED3D_TSS_COLOR_OP}, /* 1, D3DTSS_COLOROP */ - {FALSE, WINED3D_TSS_COLOR_ARG1}, /* 2, D3DTSS_COLORARG1 */ - {FALSE, WINED3D_TSS_COLOR_ARG2}, /* 3, D3DTSS_COLORARG2 */ - {FALSE, WINED3D_TSS_ALPHA_OP}, /* 4, D3DTSS_ALPHAOP */ - {FALSE, WINED3D_TSS_ALPHA_ARG1}, /* 5, D3DTSS_ALPHAARG1 */ - {FALSE, WINED3D_TSS_ALPHA_ARG2}, /* 6, D3DTSS_ALPHAARG2 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT00}, /* 7, D3DTSS_BUMPENVMAT00 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT01}, /* 8, D3DTSS_BUMPENVMAT01 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT10}, /* 9, D3DTSS_BUMPENVMAT10 */ - {FALSE, WINED3D_TSS_BUMPENV_MAT11}, /* 10, D3DTSS_BUMPENVMAT11 */ - {FALSE, WINED3D_TSS_TEXCOORD_INDEX}, /* 11, D3DTSS_TEXCOORDINDEX */ - {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 12, D3DTSS_ADDRESS */ - {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 13, D3DTSS_ADDRESSU */ - {TRUE, WINED3D_SAMP_ADDRESS_V}, /* 14, D3DTSS_ADDRESSV */ - {TRUE, WINED3D_SAMP_BORDER_COLOR}, /* 15, D3DTSS_BORDERCOLOR */ - {TRUE, WINED3D_SAMP_MAG_FILTER}, /* 16, D3DTSS_MAGFILTER */ - {TRUE, WINED3D_SAMP_MIN_FILTER}, /* 17, D3DTSS_MINFILTER */ - {TRUE, WINED3D_SAMP_MIP_FILTER}, /* 18, D3DTSS_MIPFILTER */ - {TRUE, WINED3D_SAMP_MIPMAP_LOD_BIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */ - {TRUE, WINED3D_SAMP_MAX_MIP_LEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */ - {TRUE, WINED3D_SAMP_MAX_ANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */ - {FALSE, WINED3D_TSS_BUMPENV_LSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */ - {FALSE, WINED3D_TSS_BUMPENV_LOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */ - {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ + {FALSE, {WINED3D_TSS_INVALID}}, /* 0, unused */ + {FALSE, {WINED3D_TSS_COLOR_OP}}, /* 1, D3DTSS_COLOROP */ + {FALSE, {WINED3D_TSS_COLOR_ARG1}}, /* 2, D3DTSS_COLORARG1 */ + {FALSE, {WINED3D_TSS_COLOR_ARG2}}, /* 3, D3DTSS_COLORARG2 */ + {FALSE, {WINED3D_TSS_ALPHA_OP}}, /* 4, D3DTSS_ALPHAOP */ + {FALSE, {WINED3D_TSS_ALPHA_ARG1}}, /* 5, D3DTSS_ALPHAARG1 */ + {FALSE, {WINED3D_TSS_ALPHA_ARG2}}, /* 6, D3DTSS_ALPHAARG2 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT00}}, /* 7, D3DTSS_BUMPENVMAT00 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT01}}, /* 8, D3DTSS_BUMPENVMAT01 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT10}}, /* 9, D3DTSS_BUMPENVMAT10 */ + {FALSE, {WINED3D_TSS_BUMPENV_MAT11}}, /* 10, D3DTSS_BUMPENVMAT11 */ + {FALSE, {WINED3D_TSS_TEXCOORD_INDEX}}, /* 11, D3DTSS_TEXCOORDINDEX */ + {TRUE, {WINED3D_SAMP_ADDRESS_U}}, /* 12, D3DTSS_ADDRESS */ + {TRUE, {WINED3D_SAMP_ADDRESS_U}}, /* 13, D3DTSS_ADDRESSU */ + {TRUE, {WINED3D_SAMP_ADDRESS_V}}, /* 14, D3DTSS_ADDRESSV */ + {TRUE, {WINED3D_SAMP_BORDER_COLOR}}, /* 15, D3DTSS_BORDERCOLOR */ + {TRUE, {WINED3D_SAMP_MAG_FILTER}}, /* 16, D3DTSS_MAGFILTER */ + {TRUE, {WINED3D_SAMP_MIN_FILTER}}, /* 17, D3DTSS_MINFILTER */ + {TRUE, {WINED3D_SAMP_MIP_FILTER}}, /* 18, D3DTSS_MIPFILTER */ + {TRUE, {WINED3D_SAMP_MIPMAP_LOD_BIAS}}, /* 19, D3DTSS_MIPMAPLODBIAS */ + {TRUE, {WINED3D_SAMP_MAX_MIP_LEVEL}}, /* 20, D3DTSS_MAXMIPLEVEL */ + {TRUE, {WINED3D_SAMP_MAX_ANISOTROPY}}, /* 21, D3DTSS_MAXANISOTROPY */ + {FALSE, {WINED3D_TSS_BUMPENV_LSCALE}}, /* 22, D3DTSS_BUMPENVLSCALE */ + {FALSE, {WINED3D_TSS_BUMPENV_LOFFSET}}, /* 23, D3DTSS_BUMPENVLOFFSET */ + {FALSE, {WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ }; /***************************************************************************** @@ -4803,7 +4890,6 @@ tss_lookup[] = * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if State is NULL - * For details, see IWineD3DDevice::GetTextureStageState * *****************************************************************************/ static HRESULT d3d_device7_GetTextureStageState(IDirect3DDevice7 *iface, @@ -4830,7 +4916,7 @@ static HRESULT d3d_device7_GetTextureStageState(IDirect3DDevice7 *iface, if (l->sampler_state) { - *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->state); + *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->u.sampler_state); switch (state) { @@ -4890,7 +4976,7 @@ static HRESULT d3d_device7_GetTextureStageState(IDirect3DDevice7 *iface, } else { - *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->state); + *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->u.texture_state); } wined3d_mutex_unlock(); @@ -4943,7 +5029,6 @@ static HRESULT WINAPI d3d_device3_GetTextureStageState(IDirect3DDevice3 *iface, * * Returns: * D3D_OK on success - * For details, see IWineD3DDevice::SetTextureStageState * *****************************************************************************/ static HRESULT d3d_device7_SetTextureStageState(IDirect3DDevice7 *iface, @@ -5028,11 +5113,11 @@ static HRESULT d3d_device7_SetTextureStageState(IDirect3DDevice7 *iface, break; } - wined3d_device_set_sampler_state(device->wined3d_device, stage, l->state, value); + wined3d_device_set_sampler_state(device->wined3d_device, stage, l->u.sampler_state, value); } else { - wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->state, value); + wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->u.texture_state, value); } wined3d_mutex_unlock(); @@ -5085,7 +5170,6 @@ static HRESULT WINAPI d3d_device3_SetTextureStageState(IDirect3DDevice3 *iface, * * Returns: * D3D_OK on success - * See IWineD3DDevice::ValidateDevice for more details * *****************************************************************************/ static HRESULT d3d_device7_ValidateDevice(IDirect3DDevice7 *iface, DWORD *pass_count) @@ -5146,7 +5230,6 @@ static HRESULT WINAPI d3d_device3_ValidateDevice(IDirect3DDevice3 *iface, DWORD * * Returns: * D3D_OK on success - * For details, see IWineD3DDevice::Clear * *****************************************************************************/ static HRESULT d3d_device7_Clear(IDirect3DDevice7 *iface, DWORD count, @@ -5165,6 +5248,12 @@ static HRESULT d3d_device7_Clear(IDirect3DDevice7 *iface, DWORD count, TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n", iface, count, rects, flags, color, z, stencil); + if (count && !rects) + { + WARN("count %u with NULL rects.\n", count); + count = 0; + } + wined3d_mutex_lock(); hr = wined3d_device_clear(This->wined3d_device, count, (RECT *)rects, flags, &c, z, stencil); wined3d_mutex_unlock(); @@ -5205,21 +5294,27 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Data is NULL - * For more details, see IWineDDDevice::SetViewport * *****************************************************************************/ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_viewport vp; TRACE("iface %p, viewport %p.\n", iface, viewport); if (!viewport) return DDERR_INVALIDPARAMS; - /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */ + vp.x = viewport->dwX; + vp.y = viewport->dwY; + vp.width = viewport->dwWidth; + vp.height = viewport->dwHeight; + vp.min_z = viewport->dvMinZ; + vp.max_z = viewport->dvMaxZ; + wined3d_mutex_lock(); - wined3d_device_set_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport); + wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock(); return D3D_OK; @@ -5255,23 +5350,29 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Data is NULL - * For more details, see IWineD3DDevice::GetViewport * *****************************************************************************/ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_viewport wined3d_viewport; TRACE("iface %p, viewport %p.\n", iface, viewport); if (!viewport) return DDERR_INVALIDPARAMS; - /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */ wined3d_mutex_lock(); - wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport); + wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); wined3d_mutex_unlock(); + viewport->dwX = wined3d_viewport.x; + viewport->dwY = wined3d_viewport.y; + viewport->dwWidth = wined3d_viewport.width; + viewport->dwHeight = wined3d_viewport.height; + viewport->dvMinZ = wined3d_viewport.min_z; + viewport->dvMaxZ = wined3d_viewport.max_z; + return D3D_OK; } @@ -5305,7 +5406,6 @@ static HRESULT WINAPI d3d_device7_GetViewport_FPUPreserve(IDirect3DDevice7 *ifac * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Mat is NULL. - * For more details, see IWineD3DDevice::SetMaterial * *****************************************************************************/ static HRESULT d3d_device7_SetMaterial(IDirect3DDevice7 *iface, D3DMATERIAL7 *material) @@ -5355,7 +5455,6 @@ static HRESULT WINAPI d3d_device7_SetMaterial_FPUPreserve(IDirect3DDevice7 *ifac * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Mat is NULL - * For more details, see IWineD3DDevice::GetMaterial * *****************************************************************************/ static HRESULT d3d_device7_GetMaterial(IDirect3DDevice7 *iface, D3DMATERIAL7 *material) @@ -5402,7 +5501,6 @@ static HRESULT WINAPI d3d_device7_GetMaterial_FPUPreserve(IDirect3DDevice7 *ifac * * Returns: * D3D_OK on success - * For more details, see IWineD3DDevice::SetLight * *****************************************************************************/ static HRESULT d3d_device7_SetLight(IDirect3DDevice7 *iface, DWORD light_idx, D3DLIGHT7 *light) @@ -5448,7 +5546,6 @@ static HRESULT WINAPI d3d_device7_SetLight_FPUPreserve(IDirect3DDevice7 *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Light is NULL - * For details, see IWineD3DDevice::GetLight * *****************************************************************************/ static HRESULT d3d_device7_GetLight(IDirect3DDevice7 *iface, DWORD light_idx, D3DLIGHT7 *light) @@ -5493,7 +5590,6 @@ static HRESULT WINAPI d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7 *iface, * * Returns: * D3D_OK on success - * For details see IWineD3DDevice::BeginStateBlock * *****************************************************************************/ static HRESULT d3d_device7_BeginStateBlock(IDirect3DDevice7 *iface) @@ -5541,7 +5637,6 @@ static HRESULT WINAPI d3d_device7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if BlockHandle is NULL - * See IWineD3DDevice::EndStateBlock for more details * *****************************************************************************/ static HRESULT d3d_device7_EndStateBlock(IDirect3DDevice7 *iface, DWORD *stateblock) @@ -5614,7 +5709,6 @@ static HRESULT WINAPI d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *if * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Texture is NULL - * See IWineD3DSurface::PreLoad for details * *****************************************************************************/ static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7 *texture) @@ -5627,7 +5721,7 @@ static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7 return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_texture_preload(surface->wined3d_texture); + wined3d_resource_preload(wined3d_texture_get_resource(surface->wined3d_texture)); wined3d_mutex_unlock(); return D3D_OK; @@ -5715,7 +5809,6 @@ static HRESULT WINAPI d3d_device7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 * * Returns: * D3D_OK on success * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL - * See IWineD3DDevice::CaptureStateBlock for more details * *****************************************************************************/ static HRESULT d3d_device7_CaptureStateBlock(IDirect3DDevice7 *iface, DWORD stateblock) @@ -6079,11 +6172,7 @@ static HRESULT d3d_device7_Load(IDirect3DDevice7 *iface, IDirectDrawSurface7 *ds wined3d_mutex_lock(); if (!src_rect) - { - srcrect.left = srcrect.top = 0; - srcrect.right = src->surface_desc.dwWidth; - srcrect.bottom = src->surface_desc.dwHeight; - } + SetRect(&srcrect, 0, 0, src->surface_desc.dwWidth, src->surface_desc.dwHeight); else srcrect = *src_rect; @@ -6097,8 +6186,7 @@ static HRESULT d3d_device7_Load(IDirect3DDevice7 *iface, IDirectDrawSurface7 *ds * for it may be divided. If any dimension of dest is larger than source, it can't be * mip level subset, so an error can be returned early. */ - if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom || - srcrect.right > src->surface_desc.dwWidth || + if (IsRectEmpty(&srcrect) || srcrect.right > src->surface_desc.dwWidth || srcrect.bottom > src->surface_desc.dwHeight || destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth || destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight || @@ -6263,7 +6351,6 @@ static HRESULT WINAPI d3d_device7_Load_FPUPreserve(IDirect3DDevice7 *iface, IDir * * Returns: * D3D_OK on success - * For more details, see IWineD3DDevice::SetLightEnable * *****************************************************************************/ static HRESULT d3d_device7_LightEnable(IDirect3DDevice7 *iface, DWORD light_idx, BOOL enabled) @@ -6311,7 +6398,6 @@ static HRESULT WINAPI d3d_device7_LightEnable_FPUPreserve(IDirect3DDevice7 *ifac * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Enable is NULL - * See IWineD3DDevice::GetLightEnable for more details * *****************************************************************************/ static HRESULT d3d_device7_GetLightEnable(IDirect3DDevice7 *iface, DWORD light_idx, BOOL *enabled) @@ -6362,7 +6448,6 @@ static HRESULT WINAPI d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *i * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if PlaneEquation is NULL - * See IWineD3DDevice::SetClipPlane for more details * *****************************************************************************/ static HRESULT d3d_device7_SetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) @@ -6411,7 +6496,6 @@ static HRESULT WINAPI d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *ifa * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if PlaneEquation is NULL - * See IWineD3DDevice::GetClipPlane for more details * *****************************************************************************/ static HRESULT d3d_device7_GetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) diff --git a/reactos/dll/directx/wine/ddraw/executebuffer.c b/reactos/dll/directx/wine/ddraw/executebuffer.c index c54bae9e8ce..1bc5b5c5fb9 100644 --- a/reactos/dll/directx/wine/ddraw/executebuffer.c +++ b/reactos/dll/directx/wine/ddraw/executebuffer.c @@ -43,27 +43,15 @@ static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) { TRACE("lpData : %p\n", lpDesc->lpData); } -static void transform_vertex(D3DTLVERTEX *dst, const D3DMATRIX *mat, - const D3DVIEWPORT *vp, float x, float y, float z) -{ - dst->u1.sx = (x * mat->_11) + (y * mat->_21) + (z * mat->_31) + mat->_41; - dst->u2.sy = (x * mat->_12) + (y * mat->_22) + (z * mat->_32) + mat->_42; - dst->u3.sz = (x * mat->_13) + (y * mat->_23) + (z * mat->_33) + mat->_43; - dst->u4.rhw = (x * mat->_14) + (y * mat->_24) + (z * mat->_34) + mat->_44; - - dst->u1.sx = dst->u1.sx / dst->u4.rhw * vp->dvScaleX + vp->dwX + vp->dwWidth / 2; - dst->u2.sy = -dst->u2.sy / dst->u4.rhw * vp->dvScaleY + vp->dwY + vp->dwHeight / 2; - dst->u3.sz /= dst->u4.rhw; - dst->u4.rhw = 1.0f / dst->u4.rhw; -} - HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d_device *device, struct d3d_viewport *viewport) { - DWORD vs = buffer->data.dwVertexOffset; DWORD is = buffer->data.dwInstructionOffset; char *instr = (char *)buffer->desc.lpData + is; - unsigned int i; + unsigned int i, primitive_size; + struct wined3d_map_desc map_desc; + struct wined3d_box box = {0}; + HRESULT hr; if (viewport->active_device != device) { @@ -82,41 +70,88 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, for (;;) { D3DINSTRUCTION *current = (D3DINSTRUCTION *)instr; - BYTE size; - WORD count; - - count = current->wCount; - size = current->bSize; - instr += sizeof(D3DINSTRUCTION); - - switch (current->bOpcode) { - case D3DOP_POINT: { - WARN("POINT-s (%d)\n", count); - instr += count * size; - } break; + BYTE size; + WORD count; - case D3DOP_LINE: { - WARN("LINE-s (%d)\n", count); - instr += count * size; - } break; + count = current->wCount; + size = current->bSize; + instr += sizeof(*current); + primitive_size = 0; + switch (current->bOpcode) + { + case D3DOP_POINT: + { + const D3DPOINT *p = (D3DPOINT *)instr; + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_POINTLIST, 0); + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX)); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); + + for (i = 0; i < count; ++i) + wined3d_device_draw_primitive(device->wined3d_device, p[i].wFirst, p[i].wCount); + + instr += sizeof(*p) * count; + break; + } + + case D3DOP_LINE: + primitive_size = 2; + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_LINELIST, 0); + /* Drop through. */ case D3DOP_TRIANGLE: { - D3DTLVERTEX *tl_vx = buffer->vertex_data; - TRACE("TRIANGLE (%d)\n", count); + WORD *indices; + unsigned int index_pos = buffer->index_pos, index_count; + TRACE("TRIANGLE (%d)\n", count); - if (buffer->nb_indices < count * 3) + if (!count) + break; + + if (!primitive_size) { - buffer->nb_indices = count * 3; - HeapFree(GetProcessHeap(), 0, buffer->indices); - buffer->indices = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->indices) * buffer->nb_indices); + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST, 0); + primitive_size = 3; } + index_count = count * primitive_size; + + if (buffer->index_size < index_count) + { + struct wined3d_buffer *new_buffer; + unsigned int new_size = max(buffer->index_size * 2, index_count); + + hr = wined3d_buffer_create_ib(device->wined3d_device, new_size * sizeof(*indices), + WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &new_buffer); + if (FAILED(hr)) + return hr; + + buffer->index_size = new_size; + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + buffer->index_buffer = new_buffer; + index_pos = 0; + } + else if (buffer->index_size - index_count < index_pos) + { + index_pos = 0; + } + + box.left = index_pos * sizeof(*indices); + box.right = (index_pos + index_count) * sizeof(*indices); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, + &map_desc, &box, index_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); + if (FAILED(hr)) + return hr; + indices = map_desc.data; + for (i = 0; i < count; ++i) { D3DTRIANGLE *ci = (D3DTRIANGLE *)instr; - TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); - TRACE(" Flags : "); + TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); + TRACE(" Flags : "); if (TRACE_ON(ddraw)) { /* Wireframe */ @@ -137,21 +172,36 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, TRACE("STARTFLAT(%u) ", ci->wFlags); TRACE("\n"); } - buffer->indices[(i * 3) ] = ci->u1.v1; - buffer->indices[(i * 3) + 1] = ci->u2.v2; - buffer->indices[(i * 3) + 2] = ci->u3.v3; + + switch (primitive_size) + { + case 3: + indices[(i * primitive_size) + 2] = ci->u3.v3; + /* Drop through. */ + case 2: + indices[(i * primitive_size) + 1] = ci->u2.v2; + indices[(i * primitive_size) ] = ci->u1.v1; + } instr += size; } - if (count) - IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface, - D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices, - buffer->indices, count * 3, 0); - } break; - case D3DOP_MATRIXLOAD: - WARN("MATRIXLOAD-s (%d)\n", count); - instr += count * size; - break; + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->index_buffer), 0); + + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX)); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); + wined3d_device_set_index_buffer(device->wined3d_device, buffer->index_buffer, WINED3DFMT_R16_UINT, 0); + wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, index_count); + + buffer->index_pos = index_pos + index_count; + break; + } + + case D3DOP_MATRIXLOAD: + WARN("MATRIXLOAD-s (%u)\n", count); + instr += count * size; + break; case D3DOP_MATRIXMULTIPLY: TRACE("MATRIXMULTIPLY (%d)\n", count); @@ -199,7 +249,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, device->view = ci->u2.dwArg[0]; if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION) device->proj = ci->u2.dwArg[0]; - IDirect3DDevice7_SetTransform(&device->IDirect3DDevice7_iface, + IDirect3DDevice3_SetTransform(&device->IDirect3DDevice3_iface, ci->u1.dtstTransformStateType, m); } @@ -236,97 +286,59 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, break; case D3DOP_PROCESSVERTICES: - { - /* TODO: Share code with d3d_vertex_buffer7_ProcessVertices() - * and / or wined3d_device_process_vertices(). */ - D3DMATRIX view_mat, world_mat, proj_mat, mat; - TRACE("PROCESSVERTICES (%d)\n", count); - /* Get the transform and world matrix */ - /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ - wined3d_device_get_transform(device->wined3d_device, - D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); - wined3d_device_get_transform(device->wined3d_device, - D3DTRANSFORMSTATE_PROJECTION, (struct wined3d_matrix *)&proj_mat); - wined3d_device_get_transform(device->wined3d_device, - WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); - - if (TRACE_ON(ddraw)) - { - TRACE(" Projection Matrix:\n"); - dump_D3DMATRIX(&proj_mat); - TRACE(" View Matrix:\n"); - dump_D3DMATRIX(&view_mat); - TRACE(" World Matrix:\n"); - dump_D3DMATRIX(&world_mat); - } - - multiply_matrix(&mat, &view_mat, &world_mat); - multiply_matrix(&mat, &proj_mat, &mat); - for (i = 0; i < count; ++i) { D3DPROCESSVERTICES *ci = (D3DPROCESSVERTICES *)instr; - D3DTLVERTEX *dst = (D3DTLVERTEX *)buffer->vertex_data + ci->wDest; DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK; TRACE(" start %u, dest %u, count %u, flags %#x.\n", ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS) - FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); + { + static int once; + if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); + } if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n"); switch (op) { case D3DPROCESSVERTICES_TRANSFORMLIGHT: - { - const D3DVERTEX *src = (D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; - unsigned int vtx_idx; - static unsigned int once; - - if (!once++) - FIXME("Lighting not implemented.\n"); - - for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) - { - transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, - src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z); - /* No lighting yet */ - dst[vtx_idx].u5.color = 0xffffffff; /* Opaque white */ - dst[vtx_idx].u6.specular = 0xff000000; /* No specular and no fog factor */ - dst[vtx_idx].u7.tu = src[vtx_idx].u7.tu; - dst[vtx_idx].u8.tv = src[vtx_idx].u8.tv; - } - break; - } - case D3DPROCESSVERTICES_TRANSFORM: - { - const D3DLVERTEX *src = (D3DLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; - unsigned int vtx_idx; - - for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->src_vertex_buffer, buffer->src_vertex_pos, sizeof(D3DVERTEX)); + if (op == D3DPROCESSVERTICES_TRANSFORMLIGHT) { - transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, - src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z); - dst[vtx_idx].u5.color = src[vtx_idx].u4.color; - dst[vtx_idx].u6.specular = src[vtx_idx].u5.specular; - dst[vtx_idx].u7.tu = src[vtx_idx].u6.tu; - dst[vtx_idx].u8.tv = src[vtx_idx].u7.tv; + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_VERTEX)); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_LIGHTING, TRUE); } + else + { + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_LVERTEX)); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_LIGHTING, FALSE); + } + + wined3d_device_process_vertices(device->wined3d_device, ci->wStart, ci->wDest, + ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); break; - } case D3DPROCESSVERTICES_COPY: - { - const D3DTLVERTEX *src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; - - memcpy(dst, src, ci->dwCount * sizeof(*dst)); + box.left = (buffer->src_vertex_pos + ci->wStart) * sizeof(D3DTLVERTEX); + box.right = box.left + ci->dwCount * sizeof(D3DTLVERTEX); + box.top = box.front = 0; + box.bottom = box.back = 1; + wined3d_device_copy_sub_resource_region(device->wined3d_device, + wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + ci->wDest * sizeof(D3DTLVERTEX), 0, 0, + wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box); break; - } default: FIXME("Unhandled vertex processing op %#x.\n", op); @@ -336,21 +348,38 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, instr += size; } break; - } - case D3DOP_TEXTURELOAD: { - WARN("TEXTURELOAD-s (%d)\n", count); + case D3DOP_TEXTURELOAD: + TRACE("TEXTURELOAD (%u)\n", count); - instr += count * size; - } break; + for (i = 0; i < count; ++i) + { + D3DTEXTURELOAD *ci = (D3DTEXTURELOAD *)instr; + struct ddraw_surface *dst, *src; - case D3DOP_EXIT: { - TRACE("EXIT (%d)\n", count); - /* We did this instruction */ - instr += size; - /* Exit this loop */ - goto end_of_buffer; - } break; + instr += size; + + if (!(dst = ddraw_get_object(&device->handle_table, + ci->hDestTexture - 1, DDRAW_HANDLE_SURFACE))) + { + WARN("Invalid destination texture handle %#x.\n", ci->hDestTexture); + continue; + } + if (!(src = ddraw_get_object(&device->handle_table, + ci->hSrcTexture - 1, DDRAW_HANDLE_SURFACE))) + { + WARN("Invalid source texture handle %#x.\n", ci->hSrcTexture); + continue; + } + + IDirect3DTexture2_Load(&dst->IDirect3DTexture2_iface, &src->IDirect3DTexture2_iface); + } + break; + + case D3DOP_EXIT: + TRACE("EXIT (%u)\n", count); + instr += size; + goto end_of_buffer; case D3DOP_BRANCHFORWARD: TRACE("BRANCHFORWARD (%d)\n", count); @@ -367,26 +396,28 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, instr = (char*)current + ci->dwOffset; break; } - } - } else { - if (ci->bNegate) { + } + } + else + { + if (ci->bNegate) + { TRACE(" Branch to %d\n", ci->dwOffset); if (ci->dwOffset) { instr = (char*)current + ci->dwOffset; break; } - } - } + } + } - instr += size; + instr += size; } break; - case D3DOP_SPAN: { - WARN("SPAN-s (%d)\n", count); - - instr += count * size; - } break; + case D3DOP_SPAN: + WARN("SPAN-s (%u)\n", count); + instr += count * size; + break; case D3DOP_SETSTATUS: TRACE("SETSTATUS (%d)\n", count); @@ -397,12 +428,11 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, } break; - default: - ERR("Unhandled OpCode %d !!!\n",current->bOpcode); - /* Try to save ... */ - instr += count * size; - break; - } + default: + ERR("Unhandled OpCode %#x.\n",current->bOpcode); + instr += count * size; + break; + } } end_of_buffer: @@ -471,8 +501,13 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface) { if (buffer->need_free) HeapFree(GetProcessHeap(), 0, buffer->desc.lpData); - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - HeapFree(GetProcessHeap(), 0, buffer->indices); + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + if (buffer->dst_vertex_buffer) + { + wined3d_buffer_decref(buffer->src_vertex_buffer); + wined3d_buffer_decref(buffer->dst_vertex_buffer); + } HeapFree(GetProcessHeap(), 0, buffer); } @@ -561,20 +596,67 @@ static HRESULT WINAPI d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer *iface) static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data) { struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface); - DWORD nbvert; + struct wined3d_map_desc map_desc; + struct wined3d_box box = {0}; + HRESULT hr; TRACE("iface %p, data %p.\n", iface, data); + /* Skip past previous vertex data. */ + buffer->src_vertex_pos += buffer->data.dwVertexCount; + + if (buffer->vertex_size < data->dwVertexCount) + { + unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2); + struct wined3d_buffer *src_buffer, *dst_buffer; + + hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DVERTEX), + WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_SYSTEM_MEM, + NULL, &ddraw_null_wined3d_parent_ops, &src_buffer); + if (FAILED(hr)) + return hr; + + hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX), + WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); + if (FAILED(hr)) + { + wined3d_buffer_decref(src_buffer); + return hr; + } + + if (buffer->dst_vertex_buffer) + { + wined3d_buffer_decref(buffer->src_vertex_buffer); + wined3d_buffer_decref(buffer->dst_vertex_buffer); + } + buffer->src_vertex_buffer = src_buffer; + buffer->dst_vertex_buffer = dst_buffer; + buffer->vertex_size = new_size; + buffer->src_vertex_pos = 0; + } + else if (buffer->vertex_size - data->dwVertexCount < buffer->src_vertex_pos) + { + buffer->src_vertex_pos = 0; + } + + if (data->dwVertexCount) + { + box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX); + box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, + &map_desc, &box, buffer->src_vertex_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); + if (FAILED(hr)) + return hr; + + memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, + data->dwVertexCount * sizeof(D3DVERTEX)); + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0); + } + memcpy(&buffer->data, data, data->dwSize); - /* Get the number of vertices in the execute buffer */ - nbvert = buffer->data.dwVertexCount; - - /* Prepares the transformed vertex buffer */ - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - buffer->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX)); - buffer->nb_vertices = nbvert; - if (TRACE_ON(ddraw)) _dump_executedata(data); diff --git a/reactos/dll/directx/wine/ddraw/main.c b/reactos/dll/directx/wine/ddraw/main.c index 44399c84d53..ea3cbbe42de 100644 --- a/reactos/dll/directx/wine/ddraw/main.c +++ b/reactos/dll/directx/wine/ddraw/main.c @@ -194,6 +194,40 @@ void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_ha return entry->object; } +HRESULT WINAPI GetSurfaceFromDC(HDC dc, IDirectDrawSurface4 **surface, HDC *device_dc) +{ + struct ddraw *ddraw; + + TRACE("dc %p, surface %p, device_dc %p.\n", dc, surface, device_dc); + + if (!surface) + return E_INVALIDARG; + + if (!device_dc) + { + *surface = NULL; + + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry) + { + if (FAILED(IDirectDraw4_GetSurfaceFromDC(&ddraw->IDirectDraw4_iface, dc, surface))) + continue; + + *device_dc = NULL; /* FIXME */ + wined3d_mutex_unlock(); + return DD_OK; + } + wined3d_mutex_unlock(); + + *surface = NULL; + *device_dc = NULL; + + return DDERR_NOTFOUND; +} + /*********************************************************************** * * Helper function for DirectDrawCreate and friends @@ -742,68 +776,16 @@ HRESULT WINAPI DllCanUnloadNow(void) } -/*********************************************************************** - * DllRegisterServer (DDRAW.@) - */ HRESULT WINAPI DllRegisterServer(void) { return __wine_register_resources( instance ); } -/*********************************************************************** - * DllUnregisterServer (DDRAW.@) - */ HRESULT WINAPI DllUnregisterServer(void) { return __wine_unregister_resources( instance ); } -/******************************************************************************* - * DestroyCallback - * - * Callback function for the EnumSurfaces call in DllMain. - * Dumps some surface info and releases the surface - * - * Params: - * surf: The enumerated surface - * desc: it's description - * context: Pointer to the ddraw impl - * - * Returns: - * DDENUMRET_OK; - *******************************************************************************/ -static HRESULT WINAPI -DestroyCallback(IDirectDrawSurface7 *surf, - DDSURFACEDESC2 *desc, - void *context) -{ - struct ddraw_surface *Impl = impl_from_IDirectDrawSurface7(surf); - ULONG ref7, ref4, ref3, ref2, ref1, gamma_count, iface_count; - - ref7 = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */ - ref4 = Impl->ref4; - ref3 = Impl->ref3; - ref2 = Impl->ref2; - ref1 = Impl->ref1; - gamma_count = Impl->gamma_count; - - WARN("Surface %p has an reference counts of 7: %u 4: %u 3: %u 2: %u 1: %u gamma: %u\n", - Impl, ref7, ref4, ref3, ref2, ref1, gamma_count); - - /* Skip surfaces which are attached somewhere or which are - * part of a complex compound. They will get released when destroying - * the root - */ - if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) ) - return DDENUMRET_OK; - - /* Destroy the surface */ - iface_count = ddraw_surface_release_iface(Impl); - while (iface_count) iface_count = ddraw_surface_release_iface(Impl); - - return DDENUMRET_OK; -} - /*********************************************************************** * DllMain (DDRAW.0) * @@ -891,66 +873,26 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) } case DLL_PROCESS_DETACH: - if(!list_empty(&global_ddraw_list)) + if (WARN_ON(ddraw)) { - struct list *entry, *entry2; - WARN("There are still existing DirectDraw interfaces. Wine bug or buggy application?\n"); + struct ddraw *ddraw; - /* We remove elements from this loop */ - LIST_FOR_EACH_SAFE(entry, entry2, &global_ddraw_list) + LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry) { - struct ddraw *ddraw = LIST_ENTRY(entry, struct ddraw, ddraw_list_entry); - HRESULT hr; - DDSURFACEDESC2 desc; - int i; + struct ddraw_surface *surface; - WARN("DDraw %p has a refcount of %d\n", ddraw, ddraw->ref7 + ddraw->ref4 + ddraw->ref3 + ddraw->ref2 + ddraw->ref1); + WARN("DirectDraw object %p has reference counts {%u, %u, %u, %u, %u}.\n", + ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1); - /* Add references to each interface to avoid freeing them unexpectedly */ - IDirectDraw_AddRef(&ddraw->IDirectDraw_iface); - IDirectDraw2_AddRef(&ddraw->IDirectDraw2_iface); - IDirectDraw4_AddRef(&ddraw->IDirectDraw4_iface); - IDirectDraw7_AddRef(&ddraw->IDirectDraw7_iface); + if (ddraw->d3ddevice) + WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice); - /* Does a D3D device exist? Destroy it - * TODO: Destroy all Vertex buffers, Lights, Materials - * and execute buffers too - */ - if(ddraw->d3ddevice) + LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry) { - WARN("DDraw %p has d3ddevice %p attached\n", ddraw, ddraw->d3ddevice); - while(IDirect3DDevice7_Release(&ddraw->d3ddevice->IDirect3DDevice7_iface)); + WARN("Surface %p has reference counts {%u, %u, %u, %u, %u, %u}.\n", + surface, surface->ref7, surface->ref4, surface->ref3, + surface->ref2, surface->ref1, surface->gamma_count); } - - /* Destroy the swapchain after any 3D device. The 3D device - * cleanup code needs a swapchain. Specifically, it tries to - * set the current render target to the front buffer. */ - if (ddraw->wined3d_swapchain) - ddraw_destroy_swapchain(ddraw); - - /* Try to release the objects - * Do an EnumSurfaces to find any hanging surfaces - */ - memset(&desc, 0, sizeof(desc)); - desc.dwSize = sizeof(desc); - for(i = 0; i <= 1; i++) - { - hr = IDirectDraw7_EnumSurfaces(&ddraw->IDirectDraw7_iface, - DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &desc, ddraw, DestroyCallback); - if(hr != D3D_OK) - ERR("(%p) EnumSurfaces failed, prepare for trouble\n", ddraw); - } - - if (!list_empty(&ddraw->surface_list)) - ERR("DDraw %p still has surfaces attached.\n", ddraw); - - /* Release all hanging references to destroy the objects. This - * restores the screen mode too - */ - while(IDirectDraw_Release(&ddraw->IDirectDraw_iface)); - while(IDirectDraw2_Release(&ddraw->IDirectDraw2_iface)); - while(IDirectDraw4_Release(&ddraw->IDirectDraw4_iface)); - while(IDirectDraw7_Release(&ddraw->IDirectDraw7_iface)); } } diff --git a/reactos/dll/directx/wine/ddraw/palette.c b/reactos/dll/directx/wine/ddraw/palette.c index 4f5570bc2d9..2f12138efa5 100644 --- a/reactos/dll/directx/wine/ddraw/palette.c +++ b/reactos/dll/directx/wine/ddraw/palette.c @@ -80,22 +80,22 @@ static ULONG WINAPI ddraw_palette_AddRef(IDirectDrawPalette *iface) *****************************************************************************/ static ULONG WINAPI ddraw_palette_Release(IDirectDrawPalette *iface) { - struct ddraw_palette *This = impl_from_IDirectDrawPalette(iface); - ULONG ref = InterlockedDecrement(&This->ref); + struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface); + ULONG ref = InterlockedDecrement(&palette->ref); - TRACE("%p decreasing refcount to %u.\n", This, ref); + TRACE("%p decreasing refcount to %u.\n", palette, ref); if (ref == 0) { wined3d_mutex_lock(); - wined3d_palette_decref(This->wineD3DPalette); - if ((This->flags & DDPCAPS_PRIMARYSURFACE) && This->ddraw->primary) - This->ddraw->primary->palette = NULL; - if (This->ifaceToRelease) - IUnknown_Release(This->ifaceToRelease); + wined3d_palette_decref(palette->wined3d_palette); + if ((palette->flags & DDPCAPS_PRIMARYSURFACE) && palette->ddraw->primary) + palette->ddraw->primary->palette = NULL; + if (palette->ifaceToRelease) + IUnknown_Release(palette->ifaceToRelease); wined3d_mutex_unlock(); - HeapFree(GetProcessHeap(), 0, This); + HeapFree(GetProcessHeap(), 0, palette); } return ref; @@ -153,7 +153,6 @@ static HRESULT WINAPI ddraw_palette_GetCaps(IDirectDrawPalette *iface, DWORD *ca * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if PalEnt is NULL - * For details, see IWineD3DDevice::SetEntries * *****************************************************************************/ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, @@ -169,7 +168,7 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - hr = wined3d_palette_set_entries(palette->wineD3DPalette, flags, start, count, entries); + hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries); if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE) ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE); @@ -193,7 +192,6 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if PalEnt is NULL - * For details, see IWineD3DDevice::SetEntries * *****************************************************************************/ static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface, @@ -209,7 +207,7 @@ static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface, return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - hr = wined3d_palette_get_entries(palette->wineD3DPalette, flags, start, count, entries); + hr = wined3d_palette_get_entries(palette->wined3d_palette, flags, start, count, entries); wined3d_mutex_unlock(); return hr; @@ -277,7 +275,7 @@ HRESULT ddraw_palette_init(struct ddraw_palette *palette, palette->flags = flags; if (FAILED(hr = wined3d_palette_create(ddraw->wined3d_device, - wined3d_flags, entry_count, entries, &palette->wineD3DPalette))) + wined3d_flags, entry_count, entries, &palette->wined3d_palette))) { WARN("Failed to create wined3d palette, hr %#x.\n", hr); return hr; diff --git a/reactos/dll/directx/wine/ddraw/surface.c b/reactos/dll/directx/wine/ddraw/surface.c index 946ce620b58..74f2d15d271 100644 --- a/reactos/dll/directx/wine/ddraw/surface.c +++ b/reactos/dll/directx/wine/ddraw/surface.c @@ -37,6 +37,7 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * to support windowless rendering first. */ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) { + struct ddraw *ddraw = surface->ddraw; HDC surface_dc, screen_dc; int x, y, w, h; HRESULT hr; @@ -57,14 +58,14 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE if (w <= 0 || h <= 0) return DD_OK; - if (surface->ddraw->swapchain_window) + if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP)) { /* Nothing to do, we control the frontbuffer, or at least the parts we * care about. */ if (read) return DD_OK; - return wined3d_texture_blt(surface->ddraw->wined3d_frontbuffer, 0, rect, + return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect, surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); } @@ -74,7 +75,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE return hr; } if (surface->palette) - wined3d_palette_apply_to_dc(surface->palette->wineD3DPalette, surface_dc); + wined3d_palette_apply_to_dc(surface->palette->wined3d_palette, surface_dc); if (!(screen_dc = GetDC(NULL))) { @@ -467,7 +468,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD if (palette_impl) palette_impl->flags |= DDPCAPS_PRIMARYSURFACE; wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain, - palette_impl ? palette_impl->wineD3DPalette : NULL); + palette_impl ? palette_impl->wined3d_palette : NULL); ddraw_surface_update_frontbuffer(surface, NULL, FALSE); } if (palette_impl) @@ -524,13 +525,22 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) wined3d_texture_decref(surface->wined3d_texture); } -ULONG ddraw_surface_release_iface(struct ddraw_surface *This) +static ULONG ddraw_surface_release_iface(struct ddraw_surface *This) { - ULONG iface_count = InterlockedDecrement(&This->iface_count); + ULONG iface_count; + + /* Prevent the surface from being destroyed if it's still attached to + * another surface. It will be destroyed when the root is destroyed. */ + if (This->iface_count == 1 && This->attached_iface) + IUnknown_AddRef(This->attached_iface); + iface_count = InterlockedDecrement(&This->iface_count); + TRACE("%p decreasing iface count to %u.\n", This, iface_count); if (iface_count == 0) { + struct ddraw_texture *texture = wined3d_texture_get_parent(This->wined3d_texture); + struct wined3d_device *wined3d_device = texture->wined3d_device; IUnknown *release_iface = This->ifaceToRelease; /* Complex attached surfaces are destroyed implicitly when the root is released */ @@ -546,6 +556,9 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This) if (release_iface) IUnknown_Release(release_iface); + /* Release the device only after anything that may reference it (the + * wined3d texture and rendertarget view in particular) is released. */ + wined3d_device_decref(wined3d_device); } return iface_count; @@ -933,18 +946,18 @@ static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *ifac * Returns: * DD_OK on success * DDERR_INVALIDPARAMS if DDSD is NULL - * For more details, see IWineD3DSurface::LockRect * *****************************************************************************/ static HRESULT surface_lock(struct ddraw_surface *surface, - RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) + RECT *rect, DDSURFACEDESC2 *surface_desc, unsigned int surface_desc_size, + DWORD flags, HANDLE h) { - struct wined3d_box box; struct wined3d_map_desc map_desc; + struct wined3d_box box; HRESULT hr = DD_OK; - TRACE("surface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", - surface, wine_dbgstr_rect(rect), surface_desc, flags, h); + TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n", + surface, wine_dbgstr_rect(rect), surface_desc, surface_desc_size, flags, h); /* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */ wined3d_mutex_lock(); @@ -968,18 +981,13 @@ static HRESULT surface_lock(struct ddraw_surface *surface, wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - box.left = rect->left; - box.top = rect->top; - box.right = rect->right; - box.bottom = rect->bottom; - box.front = 0; - box.back = 1; + wined3d_box_set(&box, rect->left, rect->top, rect->right, rect->bottom, 0, 1); } if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE); if (SUCCEEDED(hr)) - hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), + hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags); if (FAILED(hr)) { @@ -987,10 +995,10 @@ static HRESULT surface_lock(struct ddraw_surface *surface, switch(hr) { /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more - * specific error. But since IWineD3DSurface::LockRect returns that error in this - * only occasion, keep d3d8 and d3d9 free from the return value override. There are - * many different places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it - * is much easier to do it in one place in ddraw + * specific error. But since wined3d returns that error in this only occasion, + * keep d3d8 and d3d9 free from the return value override. There are many different + * places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it is much easier + * to do it in one place in ddraw. */ case WINED3DERR_INVALIDCALL: return DDERR_SURFACEBUSY; default: return hr; @@ -1000,7 +1008,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface, if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { if (flags & DDLOCK_READONLY) - memset(&surface->ddraw->primary_lock, 0, sizeof(surface->ddraw->primary_lock)); + SetRectEmpty(&surface->ddraw->primary_lock); else if (rect) surface->ddraw->primary_lock = *rect; else @@ -1008,7 +1016,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface, } /* Windows does not set DDSD_LPSURFACE on locked surfaces. */ - DD_STRUCT_COPY_BYSIZE(surface_desc, &surface->surface_desc); + DD_STRUCT_COPY_BYSIZE_(surface_desc, &surface->surface_desc, surface_desc_size, surface->surface_desc.dwSize); surface_desc->lpSurface = map_desc.data; TRACE("locked surface returning description :\n"); @@ -1020,63 +1028,80 @@ static HRESULT surface_lock(struct ddraw_surface *surface, return DD_OK; } +static BOOL surface_validate_lock_desc(struct ddraw_surface *surface, + const DDSURFACEDESC *desc, unsigned int *size) +{ + if (!desc) + return FALSE; + + if (desc->dwSize == sizeof(DDSURFACEDESC) || desc->dwSize == sizeof(DDSURFACEDESC2)) + { + *size = desc->dwSize; + return TRUE; + } + + if (surface->version == 7 + && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE + && !(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + if (desc->dwSize >= sizeof(DDSURFACEDESC2)) + *size = sizeof(DDSURFACEDESC2); + else + *size = sizeof(DDSURFACEDESC); + return TRUE; + } + + WARN("Invalid structure size %u.\n", desc->dwSize); + return FALSE; +} + static HRESULT WINAPI ddraw_surface7_Lock(IDirectDrawSurface7 *iface, RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); + unsigned int surface_desc_size; TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); - if (!surface_desc) return DDERR_INVALIDPARAMS; - if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && - surface_desc->dwSize != sizeof(DDSURFACEDESC2)) - { - WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); + if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size)) return DDERR_INVALIDPARAMS; - } - return surface_lock(surface, rect, surface_desc, flags, h); + + return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h); } static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface); + unsigned int surface_desc_size; TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); - if (!surface_desc) return DDERR_INVALIDPARAMS; - if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && - surface_desc->dwSize != sizeof(DDSURFACEDESC2)) - { - WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); + if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size)) return DDERR_INVALIDPARAMS; - } - return surface_lock(surface, rect, surface_desc, flags, h); + + return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h); } static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect, DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface); + unsigned int surface_desc_size; DDSURFACEDESC2 surface_desc2; HRESULT hr; TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); - if (!surface_desc) return DDERR_INVALIDPARAMS; - if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && - surface_desc->dwSize != sizeof(DDSURFACEDESC2)) - { - WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); + if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size)) return DDERR_INVALIDPARAMS; - } surface_desc2.dwSize = surface_desc->dwSize; surface_desc2.dwFlags = 0; - hr = surface_lock(surface, rect, &surface_desc2, flags, h); + hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h); DDSD2_to_DDSD(&surface_desc2, surface_desc); surface_desc->dwSize = surface_desc2.dwSize; return hr; @@ -1086,23 +1111,19 @@ static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface); + unsigned int surface_desc_size; DDSURFACEDESC2 surface_desc2; HRESULT hr; TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); - if (!surface_desc) return DDERR_INVALIDPARAMS; - if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && - surface_desc->dwSize != sizeof(DDSURFACEDESC2)) - { - WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); + if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size)) return DDERR_INVALIDPARAMS; - } surface_desc2.dwSize = surface_desc->dwSize; surface_desc2.dwFlags = 0; - hr = surface_lock(surface, rect, &surface_desc2, flags, h); + hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h); DDSD2_to_DDSD(&surface_desc2, surface_desc); surface_desc->dwSize = surface_desc2.dwSize; return hr; @@ -1112,22 +1133,19 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect, DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface); + unsigned int surface_desc_size; DDSURFACEDESC2 surface_desc2; HRESULT hr; + TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); - if (!surface_desc) return DDERR_INVALIDPARAMS; - if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && - surface_desc->dwSize != sizeof(DDSURFACEDESC2)) - { - WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); + if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size)) return DDERR_INVALIDPARAMS; - } surface_desc2.dwSize = surface_desc->dwSize; surface_desc2.dwFlags = 0; - hr = surface_lock(surface, rect, &surface_desc2, flags, h); + hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h); DDSD2_to_DDSD(&surface_desc2, surface_desc); surface_desc->dwSize = surface_desc2.dwSize; return hr; @@ -1142,8 +1160,7 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect, * Rect: Not used by this implementation * * Returns: - * D3D_OK on success - * For more details, see IWineD3DSurface::UnlockRect + * D3D_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pRect) @@ -1154,7 +1171,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect)); wined3d_mutex_lock(); - hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); wined3d_mutex_unlock(); @@ -1223,7 +1240,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_mutex_lock(); - if (!(dst_impl->ddraw->cooperative_level & DDSCL_EXCLUSIVE)) + if ((dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + && !(dst_impl->ddraw->cooperative_level & DDSCL_EXCLUSIVE)) { WARN("Not in exclusive mode.\n"); wined3d_mutex_unlock(); @@ -1261,7 +1279,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; - wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); + wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); if (src_impl->sub_resource_idx) @@ -1292,7 +1310,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; - wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); + wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); ddraw_texture = prev_ddraw_texture; @@ -1309,7 +1327,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE); wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); src_impl->wined3d_rtv = tmp_rtv; - wined3d_resource_set_parent(wined3d_texture_get_sub_resource(texture, 0), src_impl); + wined3d_texture_set_sub_resource_parent(texture, 0, src_impl); wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); src_impl->wined3d_texture = texture; @@ -1333,59 +1351,101 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 } static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Flip(IDirectDrawSurface4 *iface, - IDirectDrawSurface4 *dst, DWORD flags) + IDirectDrawSurface4 *src, DWORD flags) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface); - struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface4(src); - TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); + TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags); return ddraw_surface7_Flip(&surface->IDirectDrawSurface7_iface, - dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); + src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags); } static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Flip(IDirectDrawSurface3 *iface, - IDirectDrawSurface3 *dst, DWORD flags) + IDirectDrawSurface3 *src, DWORD flags) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface); - struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface3(src); - TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); + TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags); return ddraw_surface7_Flip(&surface->IDirectDrawSurface7_iface, - dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); + src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags); } static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Flip(IDirectDrawSurface2 *iface, - IDirectDrawSurface2 *dst, DWORD flags) + IDirectDrawSurface2 *src, DWORD flags) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface); - struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface2(dst); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface2(src); - TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); + TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags); return ddraw_surface7_Flip(&surface->IDirectDrawSurface7_iface, - dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); + src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags); } static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *iface, - IDirectDrawSurface *dst, DWORD flags) + IDirectDrawSurface *src, DWORD flags) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface); - struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface(dst); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src); - TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); + TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags); return ddraw_surface7_Flip(&surface->IDirectDrawSurface7_iface, - dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); + src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags); +} + +static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *dst_rect, + struct ddraw_surface *src_surface, const RECT *src_rect, DWORD flags, DWORD fill_colour, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +{ + struct wined3d_device *wined3d_device = dst_surface->ddraw->wined3d_device; + struct wined3d_color colour; + DWORD wined3d_flags; + + if (flags & DDBLT_COLORFILL) + { + if (!wined3d_colour_from_ddraw_colour(&dst_surface->surface_desc.u4.ddpfPixelFormat, + dst_surface->palette, fill_colour, &colour)) + return DDERR_INVALIDPARAMS; + + return wined3d_device_clear_rendertarget_view(wined3d_device, + ddraw_surface_get_rendertarget_view(dst_surface), + dst_rect, WINED3DCLEAR_TARGET, &colour, 0.0f, 0); + } + + if (flags & DDBLT_DEPTHFILL) + { + if (!wined3d_colour_from_ddraw_colour(&dst_surface->surface_desc.u4.ddpfPixelFormat, + dst_surface->palette, fill_colour, &colour)) + return DDERR_INVALIDPARAMS; + + return wined3d_device_clear_rendertarget_view(wined3d_device, + ddraw_surface_get_rendertarget_view(dst_surface), + dst_rect, WINED3DCLEAR_ZBUFFER, NULL, colour.r, 0); + } + + wined3d_flags = flags & ~DDBLT_ASYNC; + if (wined3d_flags & ~WINED3D_BLT_MASK) + { + FIXME("Unhandled flags %#x.\n", flags); + return E_NOTIMPL; + } + + if (!(flags & DDBLT_ASYNC)) + wined3d_flags |= WINED3D_BLT_SYNCHRONOUS; + + return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect, + src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter); } static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in, - struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags, + struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags, DWORD fill_colour, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { - struct wined3d_texture *wined3d_src_texture; - unsigned int src_sub_resource_idx; RECT src_rect, dst_rect; float scale_x, scale_y; const RECT *clip_rect; @@ -1395,16 +1455,10 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons UINT i; if (!dst_rect_in) - { - dst_rect.left = 0; - dst_rect.top = 0; - dst_rect.right = dst_surface->surface_desc.dwWidth; - dst_rect.bottom = dst_surface->surface_desc.dwHeight; - } + SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, + dst_surface->surface_desc.dwHeight); else - { dst_rect = *dst_rect_in; - } if (IsRectEmpty(&dst_rect)) return DDERR_INVALIDRECT; @@ -1412,28 +1466,17 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (src_surface) { if (!src_rect_in) - { - src_rect.left = 0; - src_rect.top = 0; - src_rect.right = src_surface->surface_desc.dwWidth; - src_rect.bottom = src_surface->surface_desc.dwHeight; - } + SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, + src_surface->surface_desc.dwHeight); else - { src_rect = *src_rect_in; - } if (IsRectEmpty(&src_rect)) return DDERR_INVALIDRECT; - - wined3d_src_texture = src_surface->wined3d_texture; - src_sub_resource_idx = src_surface->sub_resource_idx; } else { - SetRect(&src_rect, 0, 0, 0, 0); - wined3d_src_texture = NULL; - src_sub_resource_idx = 0; + SetRectEmpty(&src_rect); } if (!dst_surface->clipper) @@ -1441,8 +1484,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE); if (SUCCEEDED(hr)) - hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect, - wined3d_src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter); + hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter); if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE); @@ -1492,8 +1534,8 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons } } - if (FAILED(hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, - &clip_rect[i], wined3d_src_texture, src_sub_resource_idx, &src_rect_clipped, flags, fx, filter))) + if (FAILED(hr = ddraw_surface_blt(dst_surface, &clip_rect[i], + src_surface, &src_rect_clipped, flags, fill_colour, fx, filter))) break; if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) @@ -1520,8 +1562,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons * DDBltFx: Some extended blt parameters, connected to the flags * * Returns: - * D3D_OK on success - * See IWineD3DSurface::Blt for more details + * D3D_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *dst_rect, @@ -1530,15 +1571,34 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface); struct wined3d_blt_fx wined3d_fx; + DWORD unsupported_flags; + DWORD fill_colour = 0; HRESULT hr = DD_OK; DDBLTFX rop_fx; TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); - /* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have - * to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-) - */ + unsupported_flags = DDBLT_ALPHADEST + | DDBLT_ALPHADESTCONSTOVERRIDE + | DDBLT_ALPHADESTNEG + | DDBLT_ALPHADESTSURFACEOVERRIDE + | DDBLT_ALPHAEDGEBLEND + | DDBLT_ALPHASRC + | DDBLT_ALPHASRCCONSTOVERRIDE + | DDBLT_ALPHASRCNEG + | DDBLT_ALPHASRCSURFACEOVERRIDE + | DDBLT_ZBUFFER + | DDBLT_ZBUFFERDESTCONSTOVERRIDE + | DDBLT_ZBUFFERDESTOVERRIDE + | DDBLT_ZBUFFERSRCCONSTOVERRIDE + | DDBLT_ZBUFFERSRCOVERRIDE; + if (flags & unsupported_flags) + { + WARN("Ignoring unsupported flags %#x.\n", flags & unsupported_flags); + flags &= ~unsupported_flags; + } + if ((flags & DDBLT_KEYSRCOVERRIDE) && (!fx || flags & DDBLT_KEYSRC)) { WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n"); @@ -1608,6 +1668,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * return DDERR_INVALIDPARAMS; } + if (src_impl && src_rect + && ((ULONG)src_rect->left >= src_rect->right || src_rect->right > src_impl->surface_desc.dwWidth + || (ULONG)src_rect->top >= src_rect->bottom || src_rect->bottom > src_impl->surface_desc.dwHeight)) + { + WARN("Invalid source rectangle.\n"); + return DDERR_INVALIDRECT; + } + flags &= ~DDBLT_ROP; switch (fx->dwROP) { @@ -1638,24 +1706,29 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * } } + if (!(flags & (DDBLT_COLORFILL | DDBLT_DEPTHFILL)) && !src_impl) + { + WARN("No source surface.\n"); + return DDERR_INVALIDPARAMS; + } + if (flags & DDBLT_KEYSRC && (!src_impl || !(src_impl->surface_desc.dwFlags & DDSD_CKSRCBLT))) + { + WARN("DDBLT_KEYSRC blit without color key in surface, returning DDERR_INVALIDPARAMS\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + if (flags & DDBLT_KEYDEST && !(dst_impl->surface_desc.dwFlags & DDSD_CKDESTBLT)) { WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n"); wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - if (flags & ~WINED3D_BLT_MASK) - { - wined3d_mutex_unlock(); - FIXME("Unhandled flags %#x.\n", flags); - return E_NOTIMPL; - } - if (fx) { wined3d_fx.fx = fx->dwDDFX; - wined3d_fx.fill_color = fx->u5.dwFillColor; + fill_colour = fx->u5.dwFillColor; wined3d_fx.dst_color_key.color_space_low_value = fx->ddckDestColorkey.dwColorSpaceLowValue; wined3d_fx.dst_color_key.color_space_high_value = fx->ddckDestColorkey.dwColorSpaceHighValue; wined3d_fx.src_color_key.color_space_low_value = fx->ddckSrcColorkey.dwColorSpaceLowValue; @@ -1663,7 +1736,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 * } hr = ddraw_surface_blt_clipped(dst_impl, dst_rect, src_impl, - src_rect, flags, fx ? &wined3d_fx : NULL, WINED3D_TEXF_LINEAR); + src_rect, flags, fill_colour, fx ? &wined3d_fx : NULL, WINED3D_TEXF_LINEAR); wined3d_mutex_unlock(); switch(hr) @@ -1970,24 +2043,29 @@ static HRESULT ddraw_surface_delete_attached_surface(struct ddraw_surface *surfa } /* Find the predecessor of the detached surface */ - while (prev) + while (prev->next_attached != attachment) { - if (prev->next_attached == attachment) - break; - prev = prev->next_attached; + if (!(prev = prev->next_attached)) + { + ERR("Failed to find predecessor of %p.\n", attachment); + wined3d_mutex_unlock(); + return DDERR_SURFACENOTATTACHED; + } } - /* There must be a surface, otherwise there's a bug */ - assert(prev); - /* Unchain the surface */ prev->next_attached = attachment->next_attached; attachment->next_attached = NULL; attachment->first_attached = attachment; - /* Check if the wined3d depth stencil needs updating. */ - if (surface->ddraw->d3ddevice) - d3d_device_update_depth_stencil(surface->ddraw->d3ddevice); + /* Check if the wined3d depth stencil needs updating. Note that we don't + * just call d3d_device_update_depth_stencil() here since it uses + * QueryInterface(). Some applications, SCP - Containment Breach in + * particular, modify the QueryInterface() pointer in the surface vtbl + * but don't cleanup properly after the relevant dll is unloaded. */ + if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER + && wined3d_device_get_depth_stencil_view(surface->ddraw->wined3d_device) == surface->wined3d_rtv) + wined3d_device_set_depth_stencil_view(surface->ddraw->wined3d_device, NULL); wined3d_mutex_unlock(); /* Set attached_iface to NULL before releasing it, the surface may go @@ -2119,7 +2197,6 @@ static HRESULT WINAPI ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface *ifa * Returns: * DD_OK on success * DDERR_INVALIDPARAMS if hdc is NULL - * For details, see IWineD3DSurface::GetDC * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) @@ -2133,7 +2210,9 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + if (surface->dc) + hr = DDERR_DCALREADYCREATED; + else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); if (SUCCEEDED(hr)) hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); @@ -2154,7 +2233,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) palette = NULL; if (palette) - wined3d_palette_apply_to_dc(palette->wineD3DPalette, *dc); + wined3d_palette_apply_to_dc(palette->wined3d_palette, *dc); } } @@ -2165,7 +2244,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) * does not touch *dc. */ case WINED3DERR_INVALIDCALL: *dc = NULL; - return DDERR_INVALIDPARAMS; + return DDERR_CANTCREATEDC; default: return hr; @@ -2217,8 +2296,7 @@ static HRESULT WINAPI ddraw_surface1_GetDC(IDirectDrawSurface *iface, HDC *dc) * hdc: HDC to release * * Returns: - * DD_OK on success - * For more details, see IWineD3DSurface::ReleaseDC + * DD_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC hdc) @@ -2229,7 +2307,11 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h TRACE("iface %p, dc %p.\n", iface, hdc); wined3d_mutex_lock(); - if (SUCCEEDED(hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, hdc))) + if (!surface->dc) + { + hr = DDERR_NODC; + } + else if (SUCCEEDED(hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, hdc))) { surface->dc = NULL; if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) @@ -2430,8 +2512,7 @@ static HRESULT WINAPI ddraw_surface7_GetPriority(IDirectDrawSurface7 *iface, DWO * Flags: Some flags * * Returns: - * D3D_OK on success - * For more details, see IWineD3DSurface::SetPrivateData + * D3D_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_SetPrivateData(IDirectDrawSurface7 *iface, @@ -2479,7 +2560,6 @@ static HRESULT WINAPI ddraw_surface4_SetPrivateData(IDirectDrawSurface4 *iface, * Returns: * DD_OK on success * DDERR_INVALIDPARAMS if Data is NULL - * For more details, see IWineD3DSurface::GetPrivateData * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_GetPrivateData(IDirectDrawSurface7 *iface, REFGUID tag, void *data, DWORD *size) @@ -2543,8 +2623,7 @@ static HRESULT WINAPI ddraw_surface4_GetPrivateData(IDirectDrawSurface4 *iface, * tag: Tag of the data to free * * Returns: - * D3D_OK on success - * For more details, see IWineD3DSurface::FreePrivateData + * D3D_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_FreePrivateData(IDirectDrawSurface7 *iface, REFGUID tag) @@ -2976,9 +3055,6 @@ static HRESULT WINAPI ddraw_surface1_EnumOverlayZOrders(IDirectDrawSurface *ifac * Params: * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE * - * Returns: - * See IWineD3DSurface::Blt - * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_GetBltStatus(IDirectDrawSurface7 *iface, DWORD Flags) { @@ -3148,9 +3224,6 @@ static HRESULT WINAPI ddraw_surface1_GetColorKey(IDirectDrawSurface *iface, DWOR * Params: * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE * - * Returns: - * See IWineD3DSurface::GetFlipStatus - * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_GetFlipStatus(IDirectDrawSurface7 *iface, DWORD Flags) { @@ -3526,7 +3599,6 @@ static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface, * Returns: * DD_OK, if the surface is usable * DDERR_ISLOST if the surface is lost - * See IWineD3DSurface::IsLost for more details * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_IsLost(IDirectDrawSurface7 *iface) @@ -3584,8 +3656,7 @@ static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface) * doesn't reload its old contents * * Returns: - * DD_OK on success - * See IWineD3DSurface::Restore for more details + * DD_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface) @@ -3594,6 +3665,40 @@ static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface) TRACE("iface %p.\n", iface); + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + struct wined3d_swapchain *swapchain = surface->ddraw->wined3d_swapchain; + struct wined3d_sub_resource_desc wined3d_desc; + struct wined3d_display_mode mode; + HRESULT hr; + + if (FAILED(hr = wined3d_swapchain_get_display_mode(swapchain, &mode, NULL))) + { + WARN("Failed to get display mode, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, 0, &wined3d_desc))) + { + WARN("Failed to get resource desc, hr %#x.\n", hr); + return hr; + } + + if (mode.width != wined3d_desc.width || mode.height != wined3d_desc.height) + { + WARN("Display mode dimensions %ux%u don't match surface dimensions %ux%u.\n", + mode.width, mode.height, wined3d_desc.width, wined3d_desc.height); + return DDERR_WRONGMODE; + } + + if (mode.format_id != wined3d_desc.format) + { + WARN("Display mode format %#x doesn't match surface format %#x.\n", + mode.format_id, wined3d_desc.format); + return DDERR_WRONGMODE; + } + } + ddraw_update_lost_surfaces(surface->ddraw); surface->is_lost = FALSE; @@ -4125,8 +4230,7 @@ static HRESULT WINAPI ddraw_surface7_GetLOD(IDirectDrawSurface7 *iface, DWORD *M * trans: Type of transfer. Some DDBLTFAST_* flags * * Returns: - * DD_OK on success - * For more details, see IWineD3DSurface::BltFast + * DD_OK on success, error code otherwise. * *****************************************************************************/ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, @@ -4134,10 +4238,10 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac { struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface); + DWORD flags = WINED3D_BLT_SYNCHRONOUS; DWORD src_w, src_h, dst_w, dst_h; HRESULT hr = DD_OK; RECT dst_rect, s; - DWORD flags = 0; TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans); @@ -4277,7 +4381,7 @@ static HRESULT WINAPI ddraw_surface7_GetClipper(IDirectDrawSurface7 *iface, IDir return DDERR_NOCLIPPERATTACHED; } - *Clipper = (IDirectDrawClipper *)surface->clipper; + *Clipper = &surface->clipper->IDirectDrawClipper_iface; IDirectDrawClipper_AddRef(*Clipper); wined3d_mutex_unlock(); @@ -5001,8 +5105,7 @@ static HRESULT WINAPI d3d_texture1_Unload(IDirect3DTexture *iface) /***************************************************************************** * IDirect3DTexture2::GetHandle * - * Returns handle for the texture. At the moment, the interface - * to the IWineD3DTexture is used. + * Returns handle for the texture. * * Params: * device: Device this handle is assigned to @@ -5627,20 +5730,10 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren TRACE("surface %p.\n", surface); - /* Check for attached surfaces and detach them. */ + /* This shouldn't happen, ddraw_surface_release_iface() should prevent the + * surface from being destroyed in this case. */ if (surface->first_attached != surface) - { - /* Well, this shouldn't happen: The surface being attached is - * referenced in AddAttachedSurface(), so it shouldn't be released - * until DeleteAttachedSurface() is called, because the refcount is - * held. It looks like the application released it often enough to - * force this. */ - WARN("Surface is still attached to surface %p.\n", surface->first_attached); - - /* The refcount will drop to -1 here */ - if (FAILED(ddraw_surface_delete_attached_surface(surface->first_attached, surface, surface->attached_iface))) - ERR("DeleteAttachedSurface failed.\n"); - } + ERR("Surface is still attached to surface %p.\n", surface->first_attached); while (surface->next_attached) if (FAILED(ddraw_surface_delete_attached_surface(surface, @@ -5690,10 +5783,10 @@ static HRESULT CDECL ddraw_reset_enum_callback(struct wined3d_resource *resource HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) { - struct wined3d_resource_desc wined3d_desc, wined3d_mip_desc; + struct wined3d_sub_resource_desc wined3d_mip_desc; struct ddraw_surface *root, *mip, **attach; + struct wined3d_resource_desc wined3d_desc; struct wined3d_texture *wined3d_texture; - struct wined3d_resource *resource; struct wined3d_display_mode mode; DDSURFACEDESC2 *desc, *mip_desc; struct ddraw_texture *texture; @@ -5726,10 +5819,49 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ /* Ensure DDSD_CAPS is always set. */ desc->dwFlags |= DDSD_CAPS; + if (desc->ddsCaps.dwCaps & DDSCAPS_FLIP) + { + if (!(desc->dwFlags & DDSD_BACKBUFFERCOUNT) || !desc->u5.dwBackBufferCount) + { + WARN("Tried to create a flippable surface without any back buffers.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if (!(desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX)) + { + WARN("Tried to create a flippable surface without DDSCAPS_COMPLEX.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + + if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + { + WARN("Tried to create a flippable cubemap.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + + if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + { + FIXME("Flippable textures not implemented.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + } + else + { + if (desc->dwFlags & DDSD_BACKBUFFERCOUNT) + { + WARN("Tried to specify a back buffer count for a non-flippable surface.\n"); + hr = desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ? DDERR_INVALIDPARAMS : DDERR_INVALIDCAPS; + HeapFree(GetProcessHeap(), 0, texture); + return hr; + } + } + if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - DWORD flippable = desc->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_COMPLEX); - if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) { WARN("Tried to create a primary surface with DDSCAPS_TEXTURE.\n"); @@ -5737,28 +5869,18 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ return DDERR_INVALIDCAPS; } - if (flippable) + if ((desc->ddsCaps.dwCaps & DDSCAPS_COMPLEX) && !(desc->ddsCaps.dwCaps & DDSCAPS_FLIP)) { - if (flippable != (DDSCAPS_FLIP | DDSCAPS_COMPLEX)) - { - WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n"); - HeapFree(GetProcessHeap(), 0, texture); - return DDERR_INVALIDCAPS; - } + WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } - if (!(desc->dwFlags & DDSD_BACKBUFFERCOUNT) || !desc->u5.dwBackBufferCount) - { - WARN("Tried to create a flippable primary surface without any back buffers.\n"); - HeapFree(GetProcessHeap(), 0, texture); - return DDERR_INVALIDCAPS; - } - - if (!(ddraw->cooperative_level & DDSCL_EXCLUSIVE)) - { - WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n"); - HeapFree(GetProcessHeap(), 0, texture); - return DDERR_NOEXCLUSIVEMODE; - } + if ((desc->ddsCaps.dwCaps & DDSCAPS_FLIP) && !(ddraw->cooperative_level & DDSCL_EXCLUSIVE)) + { + WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_NOEXCLUSIVEMODE; } } @@ -5861,12 +5983,13 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ return DDERR_INVALIDPARAMS; } + if (desc->ddsCaps.dwCaps & DDSCAPS_FLIP) + desc->ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; + if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { /* The first surface is a front buffer, the back buffers are created * afterwards. */ - if (desc->ddsCaps.dwCaps & DDSCAPS_FLIP) - desc->ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE; if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) { @@ -5943,18 +6066,12 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ { if (!(desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE))) { - enum wined3d_resource_type rtype; DWORD usage = 0; if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - { - usage |= WINED3DUSAGE_LEGACY_CUBEMAP; - rtype = WINED3D_RTYPE_TEXTURE_2D; - } + usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - rtype = WINED3D_RTYPE_TEXTURE_2D; - else - rtype = WINED3D_RTYPE_SURFACE; + usage |= WINED3DUSAGE_TEXTURE; if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) usage = WINED3DUSAGE_DEPTHSTENCIL; @@ -5962,7 +6079,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ usage = WINED3DUSAGE_RENDERTARGET; if (SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, usage, rtype, wined3d_desc.format))) + WINED3D_DEVICE_TYPE_HAL, mode.format_id, usage, WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; else desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; @@ -5996,7 +6113,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET, - WINED3D_RTYPE_SURFACE, wined3d_desc.format))) + WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) { FIXME("Application wants to create rendering target in system memory, using video memory instead\n"); wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; @@ -6127,10 +6244,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ * address. Some of those also assume that this address is valid even when * the surface isn't mapped, and that updates done this way will be * visible on the screen. The game Nox is such an application, - * Commandos: Behind Enemy Lines is another. We set - * WINED3D_TEXTURE_CREATE_PIN_SYSMEM because of this. */ - if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels, - WINED3D_TEXTURE_CREATE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + * Commandos: Behind Enemy Lines is another. Setting + * WINED3D_TEXTURE_CREATE_GET_DC_LENIENT will ensure this. */ + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, layers, levels, + WINED3D_TEXTURE_CREATE_GET_DC_LENIENT, NULL, texture, + &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, texture); @@ -6141,6 +6259,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ wined3d_texture_decref(wined3d_texture); root->is_complex_root = TRUE; texture->root = root; + wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device); if (desc->dwFlags & DDSD_CKDESTOVERLAY) wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY, @@ -6166,8 +6285,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if (j) { - resource = wined3d_texture_get_sub_resource(wined3d_texture, i * levels + j); - wined3d_resource_get_desc(resource, &wined3d_mip_desc); + wined3d_texture_get_sub_resource_desc(wined3d_texture, i * levels + j, &wined3d_mip_desc); mip_desc->dwWidth = wined3d_mip_desc.width; mip_desc->dwHeight = wined3d_mip_desc.height; @@ -6248,8 +6366,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ desc->ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; desc->u5.dwBackBufferCount = 0; - if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, - WINED3D_TEXTURE_CREATE_PIN_SYSMEM, NULL, texture, + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, 1, + WINED3D_TEXTURE_CREATE_GET_DC_LENIENT, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { HeapFree(GetProcessHeap(), 0, texture); @@ -6260,6 +6378,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ last = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); wined3d_texture_decref(wined3d_texture); texture->root = last; + wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device); if (desc->dwFlags & DDSD_CKDESTOVERLAY) wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY, diff --git a/reactos/dll/directx/wine/ddraw/utils.c b/reactos/dll/directx/wine/ddraw/utils.c index 85bcc65a672..11d6cd4960b 100644 --- a/reactos/dll/directx/wine/ddraw/utils.c +++ b/reactos/dll/directx/wine/ddraw/utils.c @@ -481,19 +481,19 @@ enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *DDPix { case 16: if (DDPixelFormat->u2.dwStencilBitDepth == 1) return WINED3DFMT_S1_UINT_D15_UNORM; - WARN("Unknown depth stenil format: 16 z bits, %u stencil bits\n", + WARN("Unknown depth stencil format: 16 z bits, %u stencil bits.\n", DDPixelFormat->u2.dwStencilBitDepth); return WINED3DFMT_UNKNOWN; case 32: if (DDPixelFormat->u2.dwStencilBitDepth == 8) return WINED3DFMT_D24_UNORM_S8_UINT; else if (DDPixelFormat->u2.dwStencilBitDepth == 4) return WINED3DFMT_S4X4_UINT_D24_UNORM; - WARN("Unknown depth stenil format: 32 z bits, %u stencil bits\n", + WARN("Unknown depth stencil format: 32 z bits, %u stencil bits.\n", DDPixelFormat->u2.dwStencilBitDepth); return WINED3DFMT_UNKNOWN; default: - WARN("Unknown depth stenil format: %u z bits, %u stencil bits\n", + WARN("Unknown depth stencil format: %u z bits, %u stencil bits.\n", DDPixelFormat->u1.dwZBufferBitDepth, DDPixelFormat->u2.dwStencilBitDepth); return WINED3DFMT_UNKNOWN; } @@ -556,6 +556,92 @@ enum wined3d_format_id wined3dformat_from_ddrawformat(const DDPIXELFORMAT *DDPix return WINED3DFMT_UNKNOWN; } +static float colour_to_float(DWORD colour, DWORD mask) +{ + if (!mask) + return 0.0f; + return (float)(colour & mask) / (float)mask; +} + +BOOL wined3d_colour_from_ddraw_colour(const DDPIXELFORMAT *pf, const struct ddraw_palette *palette, + DWORD colour, struct wined3d_color *wined3d_colour) +{ + if (pf->dwFlags & DDPF_ALPHA) + { + DWORD size, mask; + + size = pf->u1.dwAlphaBitDepth; + mask = size < 32 ? (1u << size) - 1 : ~0u; + wined3d_colour->r = 0.0f; + wined3d_colour->g = 0.0f; + wined3d_colour->b = 0.0f; + wined3d_colour->a = colour_to_float(colour, mask); + return TRUE; + } + + if (pf->dwFlags & DDPF_FOURCC) + { + WARN("FourCC formats not supported.\n"); + goto fail; + } + + if (pf->dwFlags & DDPF_PALETTEINDEXED8) + { + PALETTEENTRY entry; + + colour &= 0xff; + if (!palette || FAILED(wined3d_palette_get_entries(palette->wined3d_palette, 0, colour, 1, &entry))) + { + wined3d_colour->r = 0.0f; + wined3d_colour->g = 0.0f; + wined3d_colour->b = 0.0f; + } + else + { + wined3d_colour->r = entry.peRed / 255.0f; + wined3d_colour->g = entry.peGreen / 255.0f; + wined3d_colour->b = entry.peBlue / 255.0f; + } + wined3d_colour->a = colour / 255.0f; + return TRUE; + } + + if (pf->dwFlags & DDPF_RGB) + { + wined3d_colour->r = colour_to_float(colour, pf->u2.dwRBitMask); + wined3d_colour->g = colour_to_float(colour, pf->u3.dwGBitMask); + wined3d_colour->b = colour_to_float(colour, pf->u4.dwBBitMask); + if (pf->dwFlags & DDPF_ALPHAPIXELS) + wined3d_colour->a = colour_to_float(colour, pf->u5.dwRGBAlphaBitMask); + else + wined3d_colour->a = 0.0f; + return TRUE; + } + + if (pf->dwFlags & DDPF_ZBUFFER) + { + wined3d_colour->r = colour_to_float(colour, pf->u3.dwZBitMask); + if (pf->dwFlags & DDPF_STENCILBUFFER) + wined3d_colour->g = colour_to_float(colour, pf->u4.dwStencilBitMask); + else + wined3d_colour->g = 0.0f; + wined3d_colour->b = 0.0f; + wined3d_colour->a = 0.0f; + return TRUE; + } + + FIXME("Unhandled pixel format.\n"); + DDRAW_dump_pixelformat(pf); + +fail: + wined3d_colour->r = 0.0f; + wined3d_colour->g = 0.0f; + wined3d_colour->b = 0.0f; + wined3d_colour->a = 0.0f; + + return FALSE; +} + /***************************************************************************** * Various dumping functions. * diff --git a/reactos/dll/directx/wine/ddraw/vertexbuffer.c b/reactos/dll/directx/wine/ddraw/vertexbuffer.c index a42ebf57abc..04d7adb94a7 100644 --- a/reactos/dll/directx/wine/ddraw/vertexbuffer.c +++ b/reactos/dll/directx/wine/ddraw/vertexbuffer.c @@ -19,11 +19,6 @@ #include "ddraw_private.h" -static inline struct d3d_vertex_buffer *impl_from_IDirect3DVertexBuffer(IDirect3DVertexBuffer *iface) -{ - return CONTAINING_RECORD(iface, struct d3d_vertex_buffer, IDirect3DVertexBuffer_iface); -} - static inline struct d3d_vertex_buffer *impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface) { return CONTAINING_RECORD(iface, struct d3d_vertex_buffer, IDirect3DVertexBuffer7_iface); @@ -33,75 +28,37 @@ static inline struct d3d_vertex_buffer *impl_from_IDirect3DVertexBuffer7(IDirect * IUnknown Methods *****************************************************************************/ -/***************************************************************************** - * IDirect3DVertexBuffer7::QueryInterface - * - * The QueryInterface Method for Vertex Buffers - * For a link to QueryInterface rules, see IDirectDraw7::QueryInterface - * - * Params - * riid: Queried Interface id - * obj: Address to return the interface pointer - * - * Returns: - * S_OK on success - * E_NOINTERFACE if the interface wasn't found - * - *****************************************************************************/ static HRESULT WINAPI d3d_vertex_buffer7_QueryInterface(IDirect3DVertexBuffer7 *iface, REFIID riid, void **obj) { struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface); TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj); - /* By default, set the object pointer to NULL */ *obj = NULL; - if ( IsEqualGUID( &IID_IUnknown, riid ) ) + if (IsEqualGUID(&IID_IUnknown, riid)) { IDirect3DVertexBuffer7_AddRef(iface); *obj = iface; - TRACE(" Creating IUnknown interface at %p.\n", *obj); return S_OK; } - if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) - { - IDirect3DVertexBuffer7_AddRef(iface); - *obj = &buffer->IDirect3DVertexBuffer_iface; - TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obj); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) + if (IsEqualGUID(&IID_IDirect3DVertexBuffer7, riid) && buffer->version == 7) + { + IDirect3DVertexBuffer7_AddRef(iface); + *obj = iface; + return S_OK; + } + if (IsEqualGUID(&IID_IDirect3DVertexBuffer, riid) && buffer->version == 3) { IDirect3DVertexBuffer7_AddRef(iface); *obj = iface; - TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obj); return S_OK; } WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); - return E_NOINTERFACE; } -static HRESULT WINAPI d3d_vertex_buffer1_QueryInterface(IDirect3DVertexBuffer *iface, REFIID riid, void **obj) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj); - - return d3d_vertex_buffer7_QueryInterface(&buffer->IDirect3DVertexBuffer7_iface, riid, obj); -} - -/***************************************************************************** - * IDirect3DVertexBuffer7::AddRef - * - * AddRef for Vertex Buffers - * - * Returns: - * The new refcount - * - *****************************************************************************/ static ULONG WINAPI d3d_vertex_buffer7_AddRef(IDirect3DVertexBuffer7 *iface) { struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface); @@ -112,25 +69,6 @@ static ULONG WINAPI d3d_vertex_buffer7_AddRef(IDirect3DVertexBuffer7 *iface) return ref; } -static ULONG WINAPI d3d_vertex_buffer1_AddRef(IDirect3DVertexBuffer *iface) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p.\n", iface); - - return d3d_vertex_buffer7_AddRef(&buffer->IDirect3DVertexBuffer7_iface); -} - - -/***************************************************************************** - * IDirect3DVertexBuffer7::Release - * - * Release for Vertex Buffers - * - * Returns: - * The new refcount - * - *****************************************************************************/ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) { struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface); @@ -138,40 +76,33 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) TRACE("%p decreasing refcount to %u.\n", buffer, ref); - if (ref == 0) + if (!ref) { - struct wined3d_buffer *curVB = NULL; + struct wined3d_buffer *vb = NULL; UINT offset, stride; - /* D3D7 Vertex buffers don't stay bound in the device, they are passed - * as a parameter to drawPrimitiveVB. DrawPrimitiveVB sets them as the - * stream source in wined3d, and they should get unset there before + /* D3D7 vertex buffers don't stay bound in the device, they are passed + * as a parameter to DrawPrimitiveVB. DrawPrimitiveVB sets them as the + * stream source in wined3d and they should get unset there before * they are destroyed. */ wined3d_mutex_lock(); - wined3d_device_get_stream_source(buffer->ddraw->wined3d_device, - 0, &curVB, &offset, &stride); - if (curVB == buffer->wineD3DVertexBuffer) + wined3d_device_get_stream_source(buffer->ddraw->wined3d_device, 0, &vb, &offset, &stride); + if (vb == buffer->wined3d_buffer) wined3d_device_set_stream_source(buffer->ddraw->wined3d_device, 0, NULL, 0, 0); - wined3d_vertex_declaration_decref(buffer->wineD3DVertexDeclaration); - wined3d_buffer_decref(buffer->wineD3DVertexBuffer); + wined3d_vertex_declaration_decref(buffer->wined3d_declaration); + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); + if (buffer->version == 7) + IDirectDraw7_Release(&buffer->ddraw->IDirectDraw7_iface); + HeapFree(GetProcessHeap(), 0, buffer); } return ref; } -static ULONG WINAPI d3d_vertex_buffer1_Release(IDirect3DVertexBuffer *iface) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p.\n", iface); - - return d3d_vertex_buffer7_Release(&buffer->IDirect3DVertexBuffer7_iface); -} - /***************************************************************************** * IDirect3DVertexBuffer Methods *****************************************************************************/ @@ -222,6 +153,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface, struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface); struct wined3d_resource_desc wined3d_desc; struct wined3d_resource *wined3d_resource; + struct wined3d_map_desc wined3d_map_desc; HRESULT hr; DWORD wined3d_flags = 0; @@ -248,8 +180,8 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface, if (SUCCEEDED(hr)) { buffer->dynamic = TRUE; - wined3d_buffer_decref(buffer->wineD3DVertexBuffer); - buffer->wineD3DVertexBuffer = new_buffer; + wined3d_buffer_decref(buffer->wined3d_buffer); + buffer->wined3d_buffer = new_buffer; } else { @@ -263,28 +195,20 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface, if (data_size) { /* Get the size, for returning it, and for locking */ - wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); *data_size = wined3d_desc.size; } - hr = wined3d_buffer_map(buffer->wineD3DVertexBuffer, 0, 0, (BYTE **)data, wined3d_flags); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer), + 0, &wined3d_map_desc, NULL, wined3d_flags); + *data = wined3d_map_desc.data; wined3d_mutex_unlock(); return hr; } -static HRESULT WINAPI d3d_vertex_buffer1_Lock(IDirect3DVertexBuffer *iface, - DWORD flags, void **data, DWORD *data_size) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size); - - return d3d_vertex_buffer7_Lock(&buffer->IDirect3DVertexBuffer7_iface, flags, data, data_size); -} - /***************************************************************************** * IDirect3DVertexBuffer7::Unlock * @@ -301,22 +225,12 @@ static HRESULT WINAPI d3d_vertex_buffer7_Unlock(IDirect3DVertexBuffer7 *iface) TRACE("iface %p.\n", iface); wined3d_mutex_lock(); - wined3d_buffer_unmap(buffer->wineD3DVertexBuffer); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0); wined3d_mutex_unlock(); return D3D_OK; } -static HRESULT WINAPI d3d_vertex_buffer1_Unlock(IDirect3DVertexBuffer *iface) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p.\n", iface); - - return d3d_vertex_buffer7_Unlock(&buffer->IDirect3DVertexBuffer7_iface); -} - - /***************************************************************************** * IDirect3DVertexBuffer7::ProcessVertices * @@ -345,7 +259,9 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 { struct d3d_vertex_buffer *dst_buffer_impl = impl_from_IDirect3DVertexBuffer7(iface); struct d3d_vertex_buffer *src_buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer7(src_buffer); - struct d3d_device *device_impl = unsafe_impl_from_IDirect3DDevice7(device); + struct d3d_device *device_impl = dst_buffer_impl->version == 7 + ? unsafe_impl_from_IDirect3DDevice7(device) + : unsafe_impl_from_IDirect3DDevice3((IDirect3DDevice3 *)device); BOOL oldClip, doClip; HRESULT hr; @@ -377,10 +293,10 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, doClip); wined3d_device_set_stream_source(device_impl->wined3d_device, - 0, src_buffer_impl->wineD3DVertexBuffer, 0, get_flexible_vertex_size(src_buffer_impl->fvf)); - wined3d_device_set_vertex_declaration(device_impl->wined3d_device, src_buffer_impl->wineD3DVertexDeclaration); + 0, src_buffer_impl->wined3d_buffer, 0, get_flexible_vertex_size(src_buffer_impl->fvf)); + wined3d_device_set_vertex_declaration(device_impl->wined3d_device, src_buffer_impl->wined3d_declaration); hr = wined3d_device_process_vertices(device_impl->wined3d_device, src_idx, dst_idx, - count, dst_buffer_impl->wineD3DVertexBuffer, NULL, flags, dst_buffer_impl->fvf); + count, dst_buffer_impl->wined3d_buffer, NULL, flags, dst_buffer_impl->fvf); /* Restore the states if needed */ if (doClip != oldClip) @@ -391,22 +307,6 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 return hr; } -static HRESULT WINAPI d3d_vertex_buffer1_ProcessVertices(IDirect3DVertexBuffer *iface, - DWORD vertex_op, DWORD dst_idx, DWORD count, IDirect3DVertexBuffer *src_buffer, - DWORD src_idx, IDirect3DDevice3 *device, DWORD flags) -{ - struct d3d_vertex_buffer *dst_buffer_impl = impl_from_IDirect3DVertexBuffer(iface); - struct d3d_vertex_buffer *src_buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer(src_buffer); - struct d3d_device *device_impl = unsafe_impl_from_IDirect3DDevice3(device); - - TRACE("iface %p, vertex_op %#x, dst_idx %u, count %u, src_buffer %p, src_idx %u, device %p, flags %#x.\n", - iface, vertex_op, dst_idx, count, src_buffer, src_idx, device, flags); - - return d3d_vertex_buffer7_ProcessVertices(&dst_buffer_impl->IDirect3DVertexBuffer7_iface, vertex_op, - dst_idx, count, &src_buffer_impl->IDirect3DVertexBuffer7_iface, src_idx, - device_impl ? &device_impl->IDirect3DDevice7_iface : NULL, flags); -} - /***************************************************************************** * IDirect3DVertexBuffer7::GetVertexBufferDesc * @@ -431,7 +331,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_GetVertexBufferDesc(IDirect3DVertexBuff if (!desc) return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer); + wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer); wined3d_resource_get_desc(wined3d_resource, &wined3d_desc); wined3d_mutex_unlock(); @@ -443,16 +343,6 @@ static HRESULT WINAPI d3d_vertex_buffer7_GetVertexBufferDesc(IDirect3DVertexBuff return D3D_OK; } -static HRESULT WINAPI d3d_vertex_buffer1_GetVertexBufferDesc(IDirect3DVertexBuffer *iface, D3DVERTEXBUFFERDESC *desc) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - - TRACE("iface %p, desc %p.\n", iface, desc); - - return d3d_vertex_buffer7_GetVertexBufferDesc(&buffer->IDirect3DVertexBuffer7_iface, desc); -} - - /***************************************************************************** * IDirect3DVertexBuffer7::Optimize * @@ -490,18 +380,6 @@ static HRESULT WINAPI d3d_vertex_buffer7_Optimize(IDirect3DVertexBuffer7 *iface, return DD_OK; } -static HRESULT WINAPI d3d_vertex_buffer1_Optimize(IDirect3DVertexBuffer *iface, - IDirect3DDevice3 *device, DWORD flags) -{ - struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer(iface); - struct d3d_device *device_impl = unsafe_impl_from_IDirect3DDevice3(device); - - TRACE("iface %p, device %p, flags %#x.\n", iface, device, flags); - - return d3d_vertex_buffer7_Optimize(&buffer->IDirect3DVertexBuffer7_iface, - device_impl ? &device_impl->IDirect3DDevice7_iface : NULL, flags); -} - /***************************************************************************** * IDirect3DVertexBuffer7::ProcessVerticesStrided * @@ -551,18 +429,6 @@ static const struct IDirect3DVertexBuffer7Vtbl d3d_vertex_buffer7_vtbl = d3d_vertex_buffer7_ProcessVerticesStrided, }; -static const struct IDirect3DVertexBufferVtbl d3d_vertex_buffer1_vtbl = -{ - d3d_vertex_buffer1_QueryInterface, - d3d_vertex_buffer1_AddRef, - d3d_vertex_buffer1_Release, - d3d_vertex_buffer1_Lock, - d3d_vertex_buffer1_Unlock, - d3d_vertex_buffer1_ProcessVertices, - d3d_vertex_buffer1_GetVertexBufferDesc, - d3d_vertex_buffer1_Optimize, -}; - HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf, struct ddraw *ddraw, D3DVERTEXBUFFERDESC *desc) { @@ -580,9 +446,10 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf, return DDERR_OUTOFMEMORY; buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl; - buffer->IDirect3DVertexBuffer_iface.lpVtbl = &d3d_vertex_buffer1_vtbl; buffer->ref = 1; - + buffer->version = ddraw->d3dversion; + if (buffer->version == 7) + IDirectDraw7_AddRef(&ddraw->IDirectDraw7_iface); buffer->ddraw = ddraw; buffer->Caps = desc->dwCaps; buffer->fvf = desc->dwFVF; @@ -590,8 +457,7 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf, wined3d_mutex_lock(); - hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, FALSE, &buffer->wineD3DVertexBuffer); - if (FAILED(hr)) + if (FAILED(hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, FALSE, &buffer->wined3d_buffer))) { WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr); if (hr == WINED3DERR_INVALIDCALL) @@ -599,15 +465,14 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf, goto end; } - buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF); - if (!buffer->wineD3DVertexDeclaration) + if (!(buffer->wined3d_declaration = ddraw_find_decl(ddraw, desc->dwFVF))) { ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF); - wined3d_buffer_decref(buffer->wineD3DVertexBuffer); + wined3d_buffer_decref(buffer->wined3d_buffer); hr = DDERR_INVALIDPARAMS; goto end; } - wined3d_vertex_declaration_incref(buffer->wineD3DVertexDeclaration); + wined3d_vertex_declaration_incref(buffer->wined3d_declaration); end: wined3d_mutex_unlock(); @@ -619,15 +484,6 @@ end: return hr; } -struct d3d_vertex_buffer *unsafe_impl_from_IDirect3DVertexBuffer(IDirect3DVertexBuffer *iface) -{ - if (!iface) - return NULL; - assert(iface->lpVtbl == &d3d_vertex_buffer1_vtbl); - - return impl_from_IDirect3DVertexBuffer(iface); -} - struct d3d_vertex_buffer *unsafe_impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface) { if (!iface) diff --git a/reactos/dll/directx/wine/ddraw/viewport.c b/reactos/dll/directx/wine/ddraw/viewport.c index 0289220d2ad..04eaa4b23a7 100644 --- a/reactos/dll/directx/wine/ddraw/viewport.c +++ b/reactos/dll/directx/wine/ddraw/viewport.c @@ -267,7 +267,6 @@ static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIE wined3d_mutex_lock(); dwSize = lpData->dwSize; - memset(lpData, 0, dwSize); if (!This->use_vp2) memcpy(lpData, &(This->viewports.vp1), dwSize); else { @@ -366,10 +365,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE * * Params: * dwVertexCount: The number of vertices to be transformed - * lpData: Pointer to the vertex data + * data: Pointer to the vertex input / output data. * dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED - * lpOffScreen: Set to the clipping plane clipping the vertex, if only one - * vertex is transformed and clipping is on. 0 otherwise + * offscreen: Logical AND of the planes that clipped the vertices if clipping + * is on. 0 if clipping is off. * * Returns: * D3D_OK on success @@ -377,76 +376,105 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE * DDERR_INVALIDPARAMS if no clipping flag is specified * *****************************************************************************/ +struct transform_vertices_vertex +{ + float x, y, z, w; /* w is unused in input data. */ + struct + { + DWORD p[4]; + } payload; +}; + static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, - DWORD dwVertexCount, D3DTRANSFORMDATA *lpData, DWORD dwFlags, DWORD *lpOffScreen) + DWORD dwVertexCount, D3DTRANSFORMDATA *data, DWORD dwFlags, DWORD *offscreen) { struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); D3DVIEWPORT vp = viewport->viewports.vp1; - D3DMATRIX view_mat, world_mat, mat; - float *in; - float *out; + D3DMATRIX view_mat, world_mat, proj_mat, mat; + struct transform_vertices_vertex *in, *out; float x, y, z, w; unsigned int i; D3DHVERTEX *outH; + struct d3d_device *device = viewport->active_device; + BOOL activate = device->current_viewport != viewport; - TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n", - iface, dwVertexCount, lpData, dwFlags, lpOffScreen); + TRACE("iface %p, vertex_count %u, data %p, flags %#x, offscreen %p.\n", + iface, dwVertexCount, data, dwFlags, offscreen); /* Tests on windows show that Windows crashes when this occurs, * so don't return the (intuitive) return value - if (!viewport->active_device) + if (!device) { WARN("No device active, returning D3DERR_VIEWPORTHASNODEVICE\n"); return D3DERR_VIEWPORTHASNODEVICE; } */ - if(!(dwFlags & (D3DTRANSFORM_UNCLIPPED | D3DTRANSFORM_CLIPPED))) + if (!data || data->dwSize != sizeof(*data)) + { + WARN("Transform data is NULL or size is incorrect, returning DDERR_INVALIDPARAMS\n"); + return DDERR_INVALIDPARAMS; + } + if (!(dwFlags & (D3DTRANSFORM_UNCLIPPED | D3DTRANSFORM_CLIPPED))) { WARN("No clipping flag passed, returning DDERR_INVALIDPARAMS\n"); return DDERR_INVALIDPARAMS; } - wined3d_mutex_lock(); - wined3d_device_get_transform(viewport->active_device->wined3d_device, - D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); - wined3d_device_get_transform(viewport->active_device->wined3d_device, - WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); - multiply_matrix(&mat, &view_mat, &world_mat); - multiply_matrix(&mat, &viewport->active_device->legacy_projection, &mat); + if (activate) + viewport_activate(viewport, TRUE); - in = lpData->lpIn; - out = lpData->lpOut; - outH = lpData->lpHOut; + wined3d_device_get_transform(device->wined3d_device, + D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&proj_mat); + multiply_matrix(&mat, &view_mat, &world_mat); + multiply_matrix(&mat, &proj_mat, &mat); + + /* The pointer is not tested against NULL on Windows. */ + if (dwFlags & D3DTRANSFORM_CLIPPED) + *offscreen = ~0U; + else + *offscreen = 0; + + outH = data->lpHOut; for(i = 0; i < dwVertexCount; i++) { - x = (in[0] * mat._11) + (in[1] * mat._21) + (in[2] * mat._31) + mat._41; - y = (in[0] * mat._12) + (in[1] * mat._22) + (in[2] * mat._32) + mat._42; - z = (in[0] * mat._13) + (in[1] * mat._23) + (in[2] * mat._33) + mat._43; - w = (in[0] * mat._14) + (in[1] * mat._24) + (in[2] * mat._34) + mat._44; + in = (struct transform_vertices_vertex *)((char *)data->lpIn + data->dwInSize * i); + out = (struct transform_vertices_vertex *)((char *)data->lpOut + data->dwOutSize * i); + + x = (in->x * mat._11) + (in->y * mat._21) + (in->z * mat._31) + mat._41; + y = (in->x * mat._12) + (in->y * mat._22) + (in->z * mat._32) + mat._42; + z = (in->x * mat._13) + (in->y * mat._23) + (in->z * mat._33) + mat._43; + w = (in->x * mat._14) + (in->y * mat._24) + (in->z * mat._34) + mat._44; if(dwFlags & D3DTRANSFORM_CLIPPED) { /* If clipping is enabled, Windows assumes that outH is - * a valid pointer - */ - outH[i].u1.hx = x; outH[i].u2.hy = y; outH[i].u3.hz = z; + * a valid pointer. */ + outH[i].u1.hx = (x - device->legacy_clipspace._41 * w) / device->legacy_clipspace._11; + outH[i].u2.hy = (y - device->legacy_clipspace._42 * w) / device->legacy_clipspace._22; + outH[i].u3.hz = (z - device->legacy_clipspace._43 * w) / device->legacy_clipspace._33; outH[i].dwFlags = 0; - if(x * vp.dvScaleX > ((float) vp.dwWidth * 0.5)) + if (x > w) outH[i].dwFlags |= D3DCLIP_RIGHT; - if(x * vp.dvScaleX <= -((float) vp.dwWidth) * 0.5) + if (x < -w) outH[i].dwFlags |= D3DCLIP_LEFT; - if(y * vp.dvScaleY > ((float) vp.dwHeight * 0.5)) + if (y > w) outH[i].dwFlags |= D3DCLIP_TOP; - if(y * vp.dvScaleY <= -((float) vp.dwHeight) * 0.5) + if (y < -w) outH[i].dwFlags |= D3DCLIP_BOTTOM; - if(z < 0.0) + if (z < 0.0f) outH[i].dwFlags |= D3DCLIP_FRONT; - if(z > 1.0) + if (z > w) outH[i].dwFlags |= D3DCLIP_BACK; + *offscreen &= outH[i].dwFlags; + if(outH[i].dwFlags) { /* Looks like native just drops the vertex, leaves whatever data @@ -454,12 +482,10 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, * The exact scheme hasn't been figured out yet, but windows * definitely writes something there. */ - out[0] = x; - out[1] = y; - out[2] = z; - out[3] = w; - in = (float *) ((char *) in + lpData->dwInSize); - out = (float *) ((char *) out + lpData->dwOutSize); + out->x = x; + out->y = y; + out->z = z; + out->w = w; continue; } } @@ -467,30 +493,16 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, w = 1 / w; x *= w; y *= w; z *= w; - out[0] = vp.dwWidth / 2 + vp.dwX + x * vp.dvScaleX; - out[1] = vp.dwHeight / 2 + vp.dwY - y * vp.dvScaleY; - out[2] = z; - out[3] = w; - in = (float *) ((char *) in + lpData->dwInSize); - out = (float *) ((char *) out + lpData->dwOutSize); + out->x = (x + 1.0f) * vp.dwWidth * 0.5 + vp.dwX; + out->y = (-y + 1.0f) * vp.dwHeight * 0.5 + vp.dwY; + out->z = z; + out->w = w; + out->payload = in->payload; } - /* According to the d3d test, the offscreen flag is set only - * if exactly one vertex is transformed. Its not documented, - * but the test shows that the lpOffscreen flag is set to the - * flag combination of clipping planes that clips the vertex. - * - * If clipping is requested, Windows assumes that the offscreen - * param is a valid pointer. - */ - if(dwVertexCount == 1 && dwFlags & D3DTRANSFORM_CLIPPED) - { - *lpOffScreen = outH[0].dwFlags; - } - else if(*lpOffScreen) - { - *lpOffScreen = 0; - } + if (activate && device->current_viewport) + viewport_activate(device->current_viewport, TRUE); + wined3d_mutex_unlock(); TRACE("All done\n"); @@ -576,7 +588,7 @@ static HRESULT WINAPI d3d_viewport_GetBackground(IDirect3DViewport3 *iface, /***************************************************************************** * IDirect3DViewport3::SetBackgroundDepth * - * Sets a surface that represents the background depth. It's contents are + * Sets a surface that represents the background depth. Its contents are * used to set the depth buffer in IDirect3DViewport3::Clear * * Params: @@ -890,7 +902,6 @@ static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVI wined3d_mutex_lock(); dwSize = lpData->dwSize; - memset(lpData, 0, dwSize); if (This->use_vp2) memcpy(lpData, &(This->viewports.vp2), dwSize); else { @@ -1116,7 +1127,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); } struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface) @@ -1124,7 +1135,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); } void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) diff --git a/reactos/dll/directx/wine/wined3d/CMakeLists.txt b/reactos/dll/directx/wine/wined3d/CMakeLists.txt index dc5e6f099bd..22fa8b0c40a 100644 --- a/reactos/dll/directx/wine/wined3d/CMakeLists.txt +++ b/reactos/dll/directx/wine/wined3d/CMakeLists.txt @@ -39,7 +39,6 @@ list(APPEND SOURCE utils.c vertexdeclaration.c view.c - volume.c wined3d_main.c wined3d_private.h) diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index 7802fc98f1b..3bdbac35df9 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -73,9 +73,9 @@ enum arb_helper_value static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum arb_helper_value value) { - if (shader == WINED3D_SHADER_TYPE_GEOMETRY) + if (shader != WINED3D_SHADER_TYPE_VERTEX && shader != WINED3D_SHADER_TYPE_PIXEL) { - ERR("Geometry shaders are unsupported\n"); + ERR("Unsupported shader type '%s'.\n", debug_shader_type(shader)); return "bad"; } @@ -103,7 +103,7 @@ static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum ar case ARB_VS_REL_OFFSET: return "rel_addr_const.y"; } } - FIXME("Unmanaged %s shader helper constant requested: %u\n", + FIXME("Unmanaged %s shader helper constant requested: %u.\n", shader == WINED3D_SHADER_TYPE_PIXEL ? "pixel" : "vertex", value); switch (value) { @@ -159,7 +159,7 @@ struct arb_ps_compile_args struct ps_compile_args super; WORD bools; WORD clip; /* only a boolean, use a WORD for alignment */ - unsigned char loop_ctrl[MAX_CONST_I][3]; + unsigned char loop_ctrl[WINED3D_MAX_CONSTS_I][3]; }; struct stb_const_desc @@ -174,7 +174,7 @@ struct arb_ps_compiled_shader struct arb_ps_np2fixup_info np2fixup_info; struct stb_const_desc bumpenvmatconst[MAX_TEXTURES]; struct stb_const_desc luminanceconst[MAX_TEXTURES]; - UINT int_consts[MAX_CONST_I]; + UINT int_consts[WINED3D_MAX_CONSTS_I]; GLuint prgId; UINT ycorrection; unsigned char numbumpenvmatconsts; @@ -200,14 +200,14 @@ struct arb_vs_compile_args unsigned char samplers[4]; DWORD samplers_compare; } vertex; - unsigned char loop_ctrl[MAX_CONST_I][3]; + unsigned char loop_ctrl[WINED3D_MAX_CONSTS_I][3]; }; struct arb_vs_compiled_shader { struct arb_vs_compile_args args; GLuint prgId; - UINT int_consts[MAX_CONST_I]; + UINT int_consts[WINED3D_MAX_CONSTS_I]; char num_int_consts; char need_color_unclamp; UINT pos_fixup; @@ -285,9 +285,6 @@ struct shader_arb_priv GLuint current_fprogram_id; const struct arb_ps_compiled_shader *compiled_fprog; const struct arb_vs_compiled_shader *compiled_vprog; - GLuint depth_blt_vprogram_id; - GLuint depth_blt_fprogram_id_full[WINED3D_GL_RES_TYPE_COUNT]; - GLuint depth_blt_fprogram_id_masked[WINED3D_GL_RES_TYPE_COUNT]; BOOL use_arbfp_fixed_func; struct wine_rb_tree fragment_shaders; BOOL last_ps_const_clamped; @@ -297,7 +294,8 @@ struct shader_arb_priv DWORD ps_sig_number; unsigned int highest_dirty_ps_const, highest_dirty_vs_const; - char *vshader_const_dirty, *pshader_const_dirty; + char vshader_const_dirty[WINED3D_MAX_VS_CONSTS_F]; + char pshader_const_dirty[WINED3D_MAX_PS_CONSTS_F]; const struct wined3d_context *last_context; const struct wined3d_vertex_pipe_ops *vertex_pipe; @@ -354,21 +352,20 @@ static unsigned int reserved_vs_const(const struct arb_vshader_private *shader_d * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders) */ /* Context activation is done by the caller. */ -static unsigned int shader_arb_load_constantsF(const struct wined3d_shader *shader, +static unsigned int shader_arb_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, GLuint target_type, unsigned int max_constants, - const float *constants, char *dirty_consts) + const struct wined3d_vec4 *constants, char *dirty_consts) { struct wined3d_shader_lconst *lconst; - DWORD i, j; - unsigned int ret; + unsigned int ret, i, j; if (TRACE_ON(d3d_constants)) { - for(i = 0; i < max_constants; i++) { - if(!dirty_consts[i]) continue; - TRACE_(d3d_constants)("Loading constants %i: %f, %f, %f, %f\n", i, - constants[i * 4 + 0], constants[i * 4 + 1], - constants[i * 4 + 2], constants[i * 4 + 3]); + for (i = 0; i < max_constants; ++i) + { + if (!dirty_consts[i]) + continue; + TRACE_(d3d_constants)("Loading constant %u: %s.\n", i, debug_vec4(&constants[i])); } } @@ -381,26 +378,39 @@ static unsigned int shader_arb_load_constantsF(const struct wined3d_shader *shad /* ps 1.x supports only 8 constants, clamp only those. When switching between 1.x and higher * shaders, the first 8 constants are marked dirty for reload */ - for(; i < min(8, max_constants); i++) { - if(!dirty_consts[i]) continue; + for (; i < min(8, max_constants); ++i) + { + if (!dirty_consts[i]) + continue; dirty_consts[i] = 0; - j = 4 * i; - if (constants[j + 0] > 1.0f) lcl_const[0] = 1.0f; - else if (constants[j + 0] < -1.0f) lcl_const[0] = -1.0f; - else lcl_const[0] = constants[j + 0]; + if (constants[i].x > 1.0f) + lcl_const[0] = 1.0f; + else if (constants[i].x < -1.0f) + lcl_const[0] = -1.0f; + else + lcl_const[0] = constants[i].x; - if (constants[j + 1] > 1.0f) lcl_const[1] = 1.0f; - else if (constants[j + 1] < -1.0f) lcl_const[1] = -1.0f; - else lcl_const[1] = constants[j + 1]; + if (constants[i].y > 1.0f) + lcl_const[1] = 1.0f; + else if (constants[i].y < -1.0f) + lcl_const[1] = -1.0f; + else + lcl_const[1] = constants[i].y; - if (constants[j + 2] > 1.0f) lcl_const[2] = 1.0f; - else if (constants[j + 2] < -1.0f) lcl_const[2] = -1.0f; - else lcl_const[2] = constants[j + 2]; + if (constants[i].z > 1.0f) + lcl_const[2] = 1.0f; + else if (constants[i].z < -1.0f) + lcl_const[2] = -1.0f; + else + lcl_const[2] = constants[i].z; - if (constants[j + 3] > 1.0f) lcl_const[3] = 1.0f; - else if (constants[j + 3] < -1.0f) lcl_const[3] = -1.0f; - else lcl_const[3] = constants[j + 3]; + if (constants[i].w > 1.0f) + lcl_const[3] = 1.0f; + else if (constants[i].w < -1.0f) + lcl_const[3] = -1.0f; + else + lcl_const[3] = constants[i].w; GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, lcl_const)); } @@ -421,23 +431,30 @@ static unsigned int shader_arb_load_constantsF(const struct wined3d_shader *shad * GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, i, max_constants, constants + (i * 4))); */ - for(; i < max_constants; i++) { - if(!dirty_consts[i]) continue; + for (; i < max_constants; ++i) + { + if (!dirty_consts[i]) + continue; /* Find the next block of dirty constants */ dirty_consts[i] = 0; j = i; - for(i++; (i < max_constants) && dirty_consts[i]; i++) { + for (++i; (i < max_constants) && dirty_consts[i]; ++i) + { dirty_consts[i] = 0; } - GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, constants + (j * 4))); + GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, &constants[j].x)); } - } else { - for(; i < max_constants; i++) { - if(dirty_consts[i]) { + } + else + { + for (; i < max_constants; ++i) + { + if (dirty_consts[i]) + { dirty_consts[i] = 0; - GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4))); + GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i].x)); } } } @@ -564,14 +581,14 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g if (!gl_shader->num_int_consts) return; - for(i = 0; i < MAX_CONST_I; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED) { float val[4]; - val[0] = (float)state->ps_consts_i[4 * i]; - val[1] = (float)state->ps_consts_i[4 * i + 1]; - val[2] = (float)state->ps_consts_i[4 * i + 2]; + val[0] = (float)state->ps_consts_i[i].x; + val[1] = (float)state->ps_consts_i[i].y; + val[2] = (float)state->ps_consts_i[i].z; val[3] = -1.0f; GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->int_consts[i], val)); @@ -594,14 +611,14 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g if (!gl_shader->num_int_consts) return; - for(i = 0; i < MAX_CONST_I; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED) { float val[4]; - val[0] = (float)state->vs_consts_i[4 * i]; - val[1] = (float)state->vs_consts_i[4 * i + 1]; - val[2] = (float)state->vs_consts_i[4 * i + 2]; + val[0] = (float)state->vs_consts_i[i].x; + val[1] = (float)state->vs_consts_i[i].y; + val[2] = (float)state->vs_consts_i[i].z; val[3] = -1.0f; GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->int_consts[i], val)); @@ -669,7 +686,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog; /* Load DirectX 9 float constants for vertex shader */ - priv->highest_dirty_vs_const = shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, + priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, priv->highest_dirty_vs_const, state->vs_consts_f, priv->vshader_const_dirty); shader_arb_vs_local_constants(gl_shader, context, state); } @@ -678,14 +695,10 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, { const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; -#if defined(STAGING_CSMT) - UINT rt_height = state->fb.render_targets[0]->height; -#else /* STAGING_CSMT */ UINT rt_height = state->fb->render_targets[0]->height; -#endif /* STAGING_CSMT */ /* Load DirectX 9 float constants for pixel shader */ - priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, + priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty); shader_arb_ps_local_constants(gl_shader, context, state, rt_height); @@ -707,16 +720,11 @@ static void shader_arb_update_float_vertex_constants(struct wined3d_device *devi { struct wined3d_context *context = context_get_current(); struct shader_arb_priv *priv = device->shader_priv; - unsigned int i; - - for (i = 0; i < device->context_count; ++i) - { - device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; - } /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->swapchain->device != device) return; + if (!context || context->device != device) + return; memset(priv->vshader_const_dirty + start, 1, sizeof(*priv->vshader_const_dirty) * count); priv->highest_dirty_vs_const = max(priv->highest_dirty_vs_const, start + count); @@ -726,16 +734,11 @@ static void shader_arb_update_float_pixel_constants(struct wined3d_device *devic { struct wined3d_context *context = context_get_current(); struct shader_arb_priv *priv = device->shader_priv; - unsigned int i; - - for (i = 0; i < device->context_count; ++i) - { - device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; - } /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->swapchain->device != device) return; + if (!context || context->device != device) + return; memset(priv->pshader_const_dirty + start, 1, sizeof(*priv->pshader_const_dirty) * count); priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count); @@ -810,7 +813,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader if(use_nv_clip(gl_info) && ctx->target_version >= NV2) { if(ctx->cur_vs_args->super.clip_enabled) - clip_limit = gl_info->limits.clipplanes; + clip_limit = gl_info->limits.user_clip_distances; else clip_limit = 0; } @@ -823,13 +826,16 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader max_constantsF -= *num_clipplanes; if(*num_clipplanes < clip_limit) { - WARN("Only %u clipplanes out of %u enabled\n", *num_clipplanes, gl_info->limits.clipplanes); + WARN("Only %u clip planes out of %u enabled.\n", *num_clipplanes, + gl_info->limits.user_clip_distances); } } else { - if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes; - else *num_clipplanes = min(gl_info->limits.clipplanes, 4); + if (ctx->target_version >= NV2) + *num_clipplanes = gl_info->limits.user_clip_distances; + else + *num_clipplanes = min(gl_info->limits.user_clip_distances, 4); } } @@ -1364,7 +1370,7 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi mod = ins->dst[0].modifiers; - /* Silently ignore PARTIALPRECISION if its not supported */ + /* Silently ignore PARTIALPRECISION if it's not supported */ if(priv->target_version == ARB) mod &= ~WINED3DSPDM_PARTIALPRECISION; if(mod & WINED3DSPDM_MSAMPCENTROID) @@ -3220,7 +3226,7 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, unsigned int cur_clip = 0; const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO); - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { if (args->clip.boolclip.clipplane_mask & (1u << i)) { @@ -3254,22 +3260,24 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that. */ - shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); - shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); - shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); + if (!gl_info->supported[ARB_CLIP_CONTROL]) + { + shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); + shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); + shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); - /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c - * and the glsl equivalent - */ - if (need_helper_const(shader_data, reg_maps, gl_info)) - { - const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); - shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); - } - else - { - shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); - shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); + /* Z coord [0;1]->[-1;1] mapping, see comment in + * get_projection_matrix() in utils.c. */ + if (need_helper_const(shader_data, reg_maps, gl_info)) + { + const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); + shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); + } + else + { + shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); + shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); + } } shader_addline(buffer, "MOV result.position, TMP_OUT;\n"); @@ -3341,120 +3349,6 @@ static BOOL shader_arb_compile(const struct wined3d_gl_info *gl_info, GLenum tar return TRUE; } -/* Context activation is done by the caller. */ -static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_info) -{ - GLuint program_id = 0; - - static const char blt_vprogram[] = - "!!ARBvp1.0\n" - "PARAM c[1] = { { 1, 0.5 } };\n" - "MOV result.position, vertex.position;\n" - "MOV result.color, c[0].x;\n" - "MOV result.texcoord[0], vertex.texcoord[0];\n" - "END\n"; - - GL_EXTCALL(glGenProgramsARB(1, &program_id)); - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, program_id)); - shader_arb_compile(gl_info, GL_VERTEX_PROGRAM_ARB, blt_vprogram); - - return program_id; -} - -/* Context activation is done by the caller. */ -static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, - enum wined3d_gl_resource_type tex_type, BOOL masked) -{ - GLuint program_id = 0; - const char *fprogram; - - static const char * const blt_fprograms_full[WINED3D_GL_RES_TYPE_COUNT] = - { - /* WINED3D_GL_RES_TYPE_TEX_1D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_2D */ - "!!ARBfp1.0\n" - "TEMP R0;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_TEX_3D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_CUBE */ - "!!ARBfp1.0\n" - "TEMP R0;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_TEX_RECT */ - "!!ARBfp1.0\n" - "TEMP R0;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_BUFFER */ - NULL, - /* WINED3D_GL_RES_TYPE_RB */ - NULL, - }; - - static const char * const blt_fprograms_masked[WINED3D_GL_RES_TYPE_COUNT] = - { - /* WINED3D_GL_RES_TYPE_TEX_1D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_2D */ - "!!ARBfp1.0\n" - "PARAM mask = program.local[0];\n" - "TEMP R0;\n" - "SLT R0.xy, fragment.position, mask.zwzw;\n" - "MUL R0.x, R0.x, R0.y;\n" - "KIL -R0.x;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_TEX_3D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_CUBE */ - "!!ARBfp1.0\n" - "PARAM mask = program.local[0];\n" - "TEMP R0;\n" - "SLT R0.xy, fragment.position, mask.zwzw;\n" - "MUL R0.x, R0.x, R0.y;\n" - "KIL -R0.x;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_TEX_RECT */ - "!!ARBfp1.0\n" - "PARAM mask = program.local[0];\n" - "TEMP R0;\n" - "SLT R0.xy, fragment.position, mask.zwzw;\n" - "MUL R0.x, R0.x, R0.y;\n" - "KIL -R0.x;\n" - "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n" - "MOV result.depth.z, R0.x;\n" - "END\n", - /* WINED3D_GL_RES_TYPE_BUFFER */ - NULL, - /* WINED3D_GL_RES_TYPE_RB */ - NULL, - }; - - fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; - if (!fprogram) - { - FIXME("tex_type %#x not supported, falling back to 2D\n", tex_type); - tex_type = WINED3D_GL_RES_TYPE_TEX_2D; - fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; - } - - GL_EXTCALL(glGenProgramsARB(1, &program_id)); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id)); - shader_arb_compile(gl_info, GL_FRAGMENT_PROGRAM_ARB, fprogram); - - return program_id; -} - static void arbfp_add_sRGB_correction(struct wined3d_string_buffer *buffer, const char *fragcolor, const char *tmp1, const char *tmp2, const char *tmp3, const char *tmp4, BOOL condcode) { @@ -3610,7 +3504,6 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, const struct arb_ps_compile_args *args, struct arb_ps_compiled_shader *compiled) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const DWORD *function = shader->function; GLuint retval; char fragcolor[16]; DWORD next_local = 0; @@ -3820,7 +3713,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, i, compiled->luminanceconst[bump_const].const_num); } - for(i = 0; i < MAX_CONST_I; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED; if (reg_maps->integer_constants & (1u << i) && priv_ctx.target_version >= NV2) @@ -3910,7 +3803,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, } /* Base Shader Body */ - shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; if(args->super.srgb_correction) { arbfp_add_sRGB_correction(buffer, fragcolor, srgbtmp[0], srgbtmp[1], srgbtmp[2], srgbtmp[3], @@ -3984,7 +3878,7 @@ static void clone_sig(struct wined3d_shader_signature *new, const struct wined3d char *name; new->element_count = sig->element_count; - new->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*new->elements) * new->element_count); + new->elements = wined3d_calloc(new->element_count, sizeof(*new->elements)); for (i = 0; i < sig->element_count; ++i) { new->elements[i] = sig->elements[i]; @@ -4214,7 +4108,6 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, const struct arb_vshader_private *shader_data = shader->backend_data; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; struct shader_arb_priv *priv = shader->device->shader_priv; - const DWORD *function = shader->function; GLuint ret; DWORD next_local = 0; struct shader_arb_ctx_priv priv_ctx; @@ -4268,7 +4161,7 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info, &priv_ctx.vs_clipplanes, &priv_ctx); - for(i = 0; i < MAX_CONST_I; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED; if (reg_maps->integer_constants & (1u << i) && priv_ctx.target_version >= NV2) @@ -4324,7 +4217,8 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, /* The shader starts with the main function */ priv_ctx.in_main_func = TRUE; /* Base Shader Body */ - shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return -1; if (!priv_ctx.footer_written) vshader_add_footer(&priv_ctx, shader_data, args, reg_maps, gl_info, buffer); @@ -4541,7 +4435,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, /* This forces all local boolean constants to 1 to make them stateblock independent */ args->bools = shader->reg_maps.local_bool_consts; - for(i = 0; i < MAX_CONST_B; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { if (state->ps_consts_b[i]) args->bools |= ( 1u << i); @@ -4566,7 +4460,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, return; } - for (i = 0; i < MAX_CONST_I; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if (int_skip & (1u << i)) { @@ -4576,9 +4470,9 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, } else { - args->loop_ctrl[i][0] = state->ps_consts_i[i * 4]; - args->loop_ctrl[i][1] = state->ps_consts_i[i * 4 + 1]; - args->loop_ctrl[i][2] = state->ps_consts_i[i * 4 + 2]; + args->loop_ctrl[i][0] = state->ps_consts_i[i].x; + args->loop_ctrl[i][1] = state->ps_consts_i[i].y; + args->loop_ctrl[i][2] = state->ps_consts_i[i].z; } } } @@ -4623,7 +4517,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, /* This forces all local boolean constants to 1 to make them stateblock independent */ args->clip.boolclip.bools = shader->reg_maps.local_bool_consts; /* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */ - for(i = 0; i < MAX_CONST_B; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { if (state->vs_consts_b[i]) args->clip.boolclip.bools |= (1u << i); @@ -4643,7 +4537,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, return; } - for(i = 0; i < MAX_CONST_I; i++) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if (int_skip & (1u << i)) { @@ -4653,9 +4547,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, } else { - args->loop_ctrl[i][0] = state->vs_consts_i[i * 4]; - args->loop_ctrl[i][1] = state->vs_consts_i[i * 4 + 1]; - args->loop_ctrl[i][2] = state->vs_consts_i[i * 4 + 2]; + args->loop_ctrl[i][0] = state->vs_consts_i[i].x; + args->loop_ctrl[i][1] = state->vs_consts_i[i].y; + args->loop_ctrl[i][2] = state->vs_consts_i[i].z; } } } @@ -4710,11 +4604,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context } else { -#if defined(STAGING_CSMT) - UINT rt_height = state->fb.render_targets[0]->height; -#else /* STAGING_CSMT */ UINT rt_height = state->fb->render_targets[0]->height; -#endif /* STAGING_CSMT */ shader_arb_ps_local_constants(compiled, context, state, rt_height); } @@ -4802,6 +4692,11 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context } } +static void shader_arb_select_compute(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state) +{ + ERR("Compute pipeline not supported by the ARB shader backend.\n"); +} /* Context activation is done by the caller. */ static void shader_arb_disable(void *shader_priv, struct wined3d_context *context) @@ -4834,57 +4729,10 @@ static void shader_arb_disable(void *shader_priv, struct wined3d_context *contex context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) - | (1u << WINED3D_SHADER_TYPE_GEOMETRY); -} - -/* Context activation is done by the caller. */ -static void shader_arb_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info, - enum wined3d_gl_resource_type tex_type, const SIZE *ds_mask_size) -{ - const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy}; - BOOL masked = ds_mask_size->cx && ds_mask_size->cy; - struct shader_arb_priv *priv = shader_priv; - GLuint *blt_fprogram; - - if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id)); - gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB); - - blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type]; - if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram)); - if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask)); - gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); -} - -/* Context activation is done by the caller. */ -static void shader_arb_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) -{ - struct shader_arb_priv *priv = shader_priv; - - if (priv->current_vprogram_id) { - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id)); - checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);"); - - TRACE("Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB.\n", priv->current_vprogram_id); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB); - checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)"); - } - - if (priv->current_fprogram_id) { - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id)); - checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);"); - - TRACE("Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB.\n", priv->current_fprogram_id); - } - else if(!priv->use_arbfp_fixed_func) - { - gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB); - checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); - } + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN) + | (1u << WINED3D_SHADER_TYPE_COMPUTE); } static void shader_arb_destroy(struct wined3d_shader *shader) @@ -4901,7 +4749,7 @@ static void shader_arb_destroy(struct wined3d_shader *shader) if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL); + struct wined3d_context *context = context_acquire(device, NULL, 0); for (i = 0; i < shader_data->num_gl_shaders; ++i) { @@ -4925,7 +4773,7 @@ static void shader_arb_destroy(struct wined3d_shader *shader) if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL); + struct wined3d_context *context = context_acquire(device, NULL, 0); for (i = 0; i < shader_data->num_gl_shaders; ++i) { @@ -4971,17 +4819,8 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wine return E_FAIL; } - priv->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count); - if (!priv->vshader_const_dirty) - goto fail; memset(priv->vshader_const_dirty, 1, sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count); - - priv->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count); - if (!priv->pshader_const_dirty) - goto fail; memset(priv->pshader_const_dirty, 1, sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count); @@ -4997,14 +4836,6 @@ static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wine device->shader_priv = priv; return WINED3D_OK; - -fail: - HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty); - HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty); - fragment_pipe->free_private(device); - vertex_pipe->vp_free(device); - HeapFree(GetProcessHeap(), 0, priv); - return E_OUTOFMEMORY; } static void release_signature(struct wine_rb_entry *entry, void *context) @@ -5023,28 +4854,9 @@ static void release_signature(struct wine_rb_entry *entry, void *context) /* Context activation is done by the caller. */ static void shader_arb_free(struct wined3d_device *device) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct shader_arb_priv *priv = device->shader_priv; - int i; - - if (priv->depth_blt_vprogram_id) - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); - - for (i = 0; i < WINED3D_GL_RES_TYPE_COUNT; ++i) - { - if (priv->depth_blt_fprogram_id_full[i]) - { - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i])); - } - if (priv->depth_blt_fprogram_id_masked[i]) - { - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i])); - } - } wine_rb_destroy(&priv->signature_tree, release_signature, NULL); - HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty); - HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty); priv->fragment_pipe->free_private(device); priv->vertex_pipe->vp_free(device); HeapFree(GetProcessHeap(), 0, device->shader_priv); @@ -5059,10 +4871,7 @@ static void shader_arb_free_context_data(struct wined3d_context *context) { struct shader_arb_priv *priv; - if (!context->swapchain) - return; - - priv = context->swapchain->device->shader_priv; + priv = context->device->shader_priv; if (priv->last_context == context) priv->last_context = NULL; } @@ -5102,7 +4911,7 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh TRACE("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n"); } caps->vs_version = min(wined3d_settings.max_sm_vs, vs_version); - caps->vs_uniform_count = vs_consts; + caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, vs_consts); } else { @@ -5110,7 +4919,10 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh caps->vs_uniform_count = 0; } + caps->hs_version = 0; + caps->ds_version = 0; caps->gs_version = 0; + caps->cs_version = 0; if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { @@ -5141,7 +4953,7 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh TRACE("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n"); } caps->ps_version = min(wined3d_settings.max_sm_ps, ps_version); - caps->ps_uniform_count = ps_consts; + caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, ps_consts); caps->ps_1x_max_value = 8.0f; } else @@ -5202,148 +5014,243 @@ static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_ins static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = { - /* WINED3DSIH_ABS */ shader_hw_map2gl, - /* WINED3DSIH_ADD */ shader_hw_map2gl, - /* WINED3DSIH_AND */ NULL, - /* WINED3DSIH_BEM */ pshader_hw_bem, - /* WINED3DSIH_BREAK */ shader_hw_break, - /* WINED3DSIH_BREAKC */ shader_hw_breakc, - /* WINED3DSIH_BREAKP */ NULL, - /* WINED3DSIH_CALL */ shader_hw_call, - /* WINED3DSIH_CALLNZ */ NULL, - /* WINED3DSIH_CMP */ pshader_hw_cmp, - /* WINED3DSIH_CND */ pshader_hw_cnd, - /* WINED3DSIH_CRS */ shader_hw_map2gl, - /* WINED3DSIH_CUT */ NULL, - /* WINED3DSIH_DCL */ shader_hw_nop, - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_hw_nop, - /* WINED3DSIH_DCL_GLOBAL_FLAGS */ NULL, - /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, - /* WINED3DSIH_DCL_INPUT */ NULL, - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_hw_nop, - /* WINED3DSIH_DCL_INPUT_PS */ NULL, - /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, - /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, - /* WINED3DSIH_DCL_INPUT_SGV */ NULL, - /* WINED3DSIH_DCL_INPUT_SIV */ NULL, - /* WINED3DSIH_DCL_OUTPUT */ NULL, - /* WINED3DSIH_DCL_OUTPUT_SIV */ NULL, - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_hw_nop, - /* WINED3DSIH_DCL_SAMPLER */ NULL, - /* WINED3DSIH_DCL_TEMPS */ NULL, - /* WINED3DSIH_DCL_VERTICES_OUT */ shader_hw_nop, - /* WINED3DSIH_DEF */ shader_hw_nop, - /* WINED3DSIH_DEFB */ shader_hw_nop, - /* WINED3DSIH_DEFI */ shader_hw_nop, - /* WINED3DSIH_DIV */ NULL, - /* WINED3DSIH_DP2 */ NULL, - /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add, - /* WINED3DSIH_DP3 */ shader_hw_map2gl, - /* WINED3DSIH_DP4 */ shader_hw_map2gl, - /* WINED3DSIH_DST */ shader_hw_map2gl, - /* WINED3DSIH_DSX */ shader_hw_map2gl, - /* WINED3DSIH_DSY */ shader_hw_dsy, - /* WINED3DSIH_ELSE */ shader_hw_else, - /* WINED3DSIH_EMIT */ NULL, - /* WINED3DSIH_ENDIF */ shader_hw_endif, - /* WINED3DSIH_ENDLOOP */ shader_hw_endloop, - /* WINED3DSIH_ENDREP */ shader_hw_endrep, - /* WINED3DSIH_EQ */ NULL, - /* WINED3DSIH_EXP */ shader_hw_scalar_op, - /* WINED3DSIH_EXPP */ shader_hw_scalar_op, - /* WINED3DSIH_FRC */ shader_hw_map2gl, - /* WINED3DSIH_FTOI */ NULL, - /* WINED3DSIH_FTOU */ NULL, - /* WINED3DSIH_GE */ NULL, - /* WINED3DSIH_IADD */ NULL, - /* WINED3DSIH_IEQ */ NULL, - /* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */, - /* WINED3DSIH_IFC */ shader_hw_ifc, - /* WINED3DSIH_IGE */ NULL, - /* WINED3DSIH_ILT */ NULL, - /* WINED3DSIH_IMAD */ NULL, - /* WINED3DSIH_IMAX */ NULL, - /* WINED3DSIH_IMIN */ NULL, - /* WINED3DSIH_IMUL */ NULL, - /* WINED3DSIH_INE */ NULL, - /* WINED3DSIH_INEG */ NULL, - /* WINED3DSIH_ISHL */ NULL, - /* WINED3DSIH_ITOF */ NULL, - /* WINED3DSIH_LABEL */ shader_hw_label, - /* WINED3DSIH_LD */ NULL, - /* WINED3DSIH_LIT */ shader_hw_map2gl, - /* WINED3DSIH_LOG */ shader_hw_scalar_op, - /* WINED3DSIH_LOGP */ shader_hw_scalar_op, - /* WINED3DSIH_LOOP */ shader_hw_loop, - /* WINED3DSIH_LRP */ shader_hw_lrp, - /* WINED3DSIH_LT */ NULL, - /* WINED3DSIH_M3x2 */ shader_hw_mnxn, - /* WINED3DSIH_M3x3 */ shader_hw_mnxn, - /* WINED3DSIH_M3x4 */ shader_hw_mnxn, - /* WINED3DSIH_M4x3 */ shader_hw_mnxn, - /* WINED3DSIH_M4x4 */ shader_hw_mnxn, - /* WINED3DSIH_MAD */ shader_hw_map2gl, - /* WINED3DSIH_MAX */ shader_hw_map2gl, - /* WINED3DSIH_MIN */ shader_hw_map2gl, - /* WINED3DSIH_MOV */ shader_hw_mov, - /* WINED3DSIH_MOVA */ shader_hw_mov, - /* WINED3DSIH_MOVC */ NULL, - /* WINED3DSIH_MUL */ shader_hw_map2gl, - /* WINED3DSIH_NE */ NULL, - /* WINED3DSIH_NOP */ shader_hw_nop, - /* WINED3DSIH_NOT */ NULL, - /* WINED3DSIH_NRM */ shader_hw_nrm, - /* WINED3DSIH_OR */ NULL, - /* WINED3DSIH_PHASE */ shader_hw_nop, - /* WINED3DSIH_POW */ shader_hw_pow, - /* WINED3DSIH_RCP */ shader_hw_scalar_op, - /* WINED3DSIH_REP */ shader_hw_rep, - /* WINED3DSIH_RESINFO */ NULL, - /* WINED3DSIH_RET */ shader_hw_ret, - /* WINED3DSIH_ROUND_NI */ NULL, - /* WINED3DSIH_ROUND_PI */ NULL, - /* WINED3DSIH_ROUND_Z */ NULL, - /* WINED3DSIH_RSQ */ shader_hw_scalar_op, - /* WINED3DSIH_SAMPLE */ NULL, - /* WINED3DSIH_SAMPLE_B */ NULL, - /* WINED3DSIH_SAMPLE_C */ NULL, - /* WINED3DSIH_SAMPLE_C_LZ */ NULL, - /* WINED3DSIH_SAMPLE_GRAD */ NULL, - /* WINED3DSIH_SAMPLE_LOD */ NULL, - /* WINED3DSIH_SETP */ NULL, - /* WINED3DSIH_SGE */ shader_hw_map2gl, - /* WINED3DSIH_SGN */ shader_hw_sgn, - /* WINED3DSIH_SINCOS */ shader_hw_sincos, - /* WINED3DSIH_SLT */ shader_hw_map2gl, - /* WINED3DSIH_SQRT */ NULL, - /* WINED3DSIH_SUB */ shader_hw_map2gl, - /* WINED3DSIH_TEX */ pshader_hw_tex, - /* WINED3DSIH_TEXBEM */ pshader_hw_texbem, - /* WINED3DSIH_TEXBEML */ pshader_hw_texbem, - /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord, - /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth, - /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3, - /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex, - /* WINED3DSIH_TEXKILL */ pshader_hw_texkill, - /* WINED3DSIH_TEXLDD */ shader_hw_texldd, - /* WINED3DSIH_TEXLDL */ shader_hw_texldl, - /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth, - /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad, - /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex, - /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3, - /* WINED3DSIH_TEXM3x3DIFF */ NULL, - /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad, - /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec, - /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex, - /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec, - /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar, - /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb, - /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb, - /* WINED3DSIH_UDIV */ NULL, - /* WINED3DSIH_UGE */ NULL, - /* WINED3DSIH_USHR */ NULL, - /* WINED3DSIH_UTOF */ NULL, - /* WINED3DSIH_XOR */ NULL, + /* WINED3DSIH_ABS */ shader_hw_map2gl, + /* WINED3DSIH_ADD */ shader_hw_map2gl, + /* WINED3DSIH_AND */ NULL, + /* WINED3DSIH_ATOMIC_AND */ NULL, + /* WINED3DSIH_ATOMIC_CMP_STORE */ NULL, + /* WINED3DSIH_ATOMIC_IADD */ NULL, + /* WINED3DSIH_ATOMIC_IMAX */ NULL, + /* WINED3DSIH_ATOMIC_IMIN */ NULL, + /* WINED3DSIH_ATOMIC_OR */ NULL, + /* WINED3DSIH_ATOMIC_UMAX */ NULL, + /* WINED3DSIH_ATOMIC_UMIN */ NULL, + /* WINED3DSIH_ATOMIC_XOR */ NULL, + /* WINED3DSIH_BEM */ pshader_hw_bem, + /* WINED3DSIH_BFI */ NULL, + /* WINED3DSIH_BFREV */ NULL, + /* WINED3DSIH_BREAK */ shader_hw_break, + /* WINED3DSIH_BREAKC */ shader_hw_breakc, + /* WINED3DSIH_BREAKP */ NULL, + /* WINED3DSIH_BUFINFO */ NULL, + /* WINED3DSIH_CALL */ shader_hw_call, + /* WINED3DSIH_CALLNZ */ NULL, + /* WINED3DSIH_CASE */ NULL, + /* WINED3DSIH_CMP */ pshader_hw_cmp, + /* WINED3DSIH_CND */ pshader_hw_cnd, + /* WINED3DSIH_CONTINUE */ NULL, + /* WINED3DSIH_CONTINUEP */ NULL, + /* WINED3DSIH_COUNTBITS */ NULL, + /* WINED3DSIH_CRS */ shader_hw_map2gl, + /* WINED3DSIH_CUT */ NULL, + /* WINED3DSIH_CUT_STREAM */ NULL, + /* WINED3DSIH_DCL */ shader_hw_nop, + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_hw_nop, + /* WINED3DSIH_DCL_FUNCTION_BODY */ NULL, + /* WINED3DSIH_DCL_FUNCTION_TABLE */ NULL, + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ NULL, + /* WINED3DSIH_DCL_GS_INSTANCES */ NULL, + /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ NULL, + /* WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT */ NULL, + /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR */ NULL, + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, + /* WINED3DSIH_DCL_INDEX_RANGE */ NULL, + /* WINED3DSIH_DCL_INDEXABLE_TEMP */ NULL, + /* WINED3DSIH_DCL_INPUT */ NULL, + /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ NULL, + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_hw_nop, + /* WINED3DSIH_DCL_INPUT_PS */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, + /* WINED3DSIH_DCL_INPUT_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_SIV */ NULL, + /* WINED3DSIH_DCL_INTERFACE */ NULL, + /* WINED3DSIH_DCL_OUTPUT */ NULL, + /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT */ NULL, + /* WINED3DSIH_DCL_OUTPUT_SIV */ NULL, + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_hw_nop, + /* WINED3DSIH_DCL_RESOURCE_RAW */ NULL, + /* WINED3DSIH_DCL_RESOURCE_STRUCTURED */ NULL, + /* WINED3DSIH_DCL_SAMPLER */ NULL, + /* WINED3DSIH_DCL_STREAM */ NULL, + /* WINED3DSIH_DCL_TEMPS */ NULL, + /* WINED3DSIH_DCL_TESSELLATOR_DOMAIN */ NULL, + /* WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE */ NULL, + /* WINED3DSIH_DCL_TESSELLATOR_PARTITIONING */ NULL, + /* WINED3DSIH_DCL_TGSM_RAW */ NULL, + /* WINED3DSIH_DCL_TGSM_STRUCTURED */ NULL, + /* WINED3DSIH_DCL_THREAD_GROUP */ NULL, + /* WINED3DSIH_DCL_UAV_RAW */ NULL, + /* WINED3DSIH_DCL_UAV_STRUCTURED */ NULL, + /* WINED3DSIH_DCL_UAV_TYPED */ NULL, + /* WINED3DSIH_DCL_VERTICES_OUT */ shader_hw_nop, + /* WINED3DSIH_DEF */ shader_hw_nop, + /* WINED3DSIH_DEFAULT */ NULL, + /* WINED3DSIH_DEFB */ shader_hw_nop, + /* WINED3DSIH_DEFI */ shader_hw_nop, + /* WINED3DSIH_DIV */ NULL, + /* WINED3DSIH_DP2 */ NULL, + /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add, + /* WINED3DSIH_DP3 */ shader_hw_map2gl, + /* WINED3DSIH_DP4 */ shader_hw_map2gl, + /* WINED3DSIH_DST */ shader_hw_map2gl, + /* WINED3DSIH_DSX */ shader_hw_map2gl, + /* WINED3DSIH_DSX_COARSE */ NULL, + /* WINED3DSIH_DSX_FINE */ NULL, + /* WINED3DSIH_DSY */ shader_hw_dsy, + /* WINED3DSIH_DSY_COARSE */ NULL, + /* WINED3DSIH_DSY_FINE */ NULL, + /* WINED3DSIH_ELSE */ shader_hw_else, + /* WINED3DSIH_EMIT */ NULL, + /* WINED3DSIH_EMIT_STREAM */ NULL, + /* WINED3DSIH_ENDIF */ shader_hw_endif, + /* WINED3DSIH_ENDLOOP */ shader_hw_endloop, + /* WINED3DSIH_ENDREP */ shader_hw_endrep, + /* WINED3DSIH_ENDSWITCH */ NULL, + /* WINED3DSIH_EQ */ NULL, + /* WINED3DSIH_EXP */ shader_hw_scalar_op, + /* WINED3DSIH_EXPP */ shader_hw_scalar_op, + /* WINED3DSIH_F16TOF32 */ NULL, + /* WINED3DSIH_F32TOF16 */ NULL, + /* WINED3DSIH_FCALL */ NULL, + /* WINED3DSIH_FIRSTBIT_HI */ NULL, + /* WINED3DSIH_FIRSTBIT_LO */ NULL, + /* WINED3DSIH_FIRSTBIT_SHI */ NULL, + /* WINED3DSIH_FRC */ shader_hw_map2gl, + /* WINED3DSIH_FTOI */ NULL, + /* WINED3DSIH_FTOU */ NULL, + /* WINED3DSIH_GATHER4 */ NULL, + /* WINED3DSIH_GATHER4_C */ NULL, + /* WINED3DSIH_GATHER4_PO */ NULL, + /* WINED3DSIH_GATHER4_PO_C */ NULL, + /* WINED3DSIH_GE */ NULL, + /* WINED3DSIH_HS_CONTROL_POINT_PHASE */ NULL, + /* WINED3DSIH_HS_DECLS */ NULL, + /* WINED3DSIH_HS_FORK_PHASE */ NULL, + /* WINED3DSIH_HS_JOIN_PHASE */ NULL, + /* WINED3DSIH_IADD */ NULL, + /* WINED3DSIH_IBFE */ NULL, + /* WINED3DSIH_IEQ */ NULL, + /* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */, + /* WINED3DSIH_IFC */ shader_hw_ifc, + /* WINED3DSIH_IGE */ NULL, + /* WINED3DSIH_ILT */ NULL, + /* WINED3DSIH_IMAD */ NULL, + /* WINED3DSIH_IMAX */ NULL, + /* WINED3DSIH_IMIN */ NULL, + /* WINED3DSIH_IMM_ATOMIC_ALLOC */ NULL, + /* WINED3DSIH_IMM_ATOMIC_AND */ NULL, + /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ NULL, + /* WINED3DSIH_IMM_ATOMIC_CONSUME */ NULL, + /* WINED3DSIH_IMM_ATOMIC_EXCH */ NULL, + /* WINED3DSIH_IMM_ATOMIC_IADD */ NULL, + /* WINED3DSIH_IMM_ATOMIC_IMAX */ NULL, + /* WINED3DSIH_IMM_ATOMIC_IMIN */ NULL, + /* WINED3DSIH_IMM_ATOMIC_OR */ NULL, + /* WINED3DSIH_IMM_ATOMIC_UMAX */ NULL, + /* WINED3DSIH_IMM_ATOMIC_UMIN */ NULL, + /* WINED3DSIH_IMM_ATOMIC_XOR */ NULL, + /* WINED3DSIH_IMUL */ NULL, + /* WINED3DSIH_INE */ NULL, + /* WINED3DSIH_INEG */ NULL, + /* WINED3DSIH_ISHL */ NULL, + /* WINED3DSIH_ISHR */ NULL, + /* WINED3DSIH_ITOF */ NULL, + /* WINED3DSIH_LABEL */ shader_hw_label, + /* WINED3DSIH_LD */ NULL, + /* WINED3DSIH_LD2DMS */ NULL, + /* WINED3DSIH_LD_RAW */ NULL, + /* WINED3DSIH_LD_STRUCTURED */ NULL, + /* WINED3DSIH_LD_UAV_TYPED */ NULL, + /* WINED3DSIH_LIT */ shader_hw_map2gl, + /* WINED3DSIH_LOD */ NULL, + /* WINED3DSIH_LOG */ shader_hw_scalar_op, + /* WINED3DSIH_LOGP */ shader_hw_scalar_op, + /* WINED3DSIH_LOOP */ shader_hw_loop, + /* WINED3DSIH_LRP */ shader_hw_lrp, + /* WINED3DSIH_LT */ NULL, + /* WINED3DSIH_M3x2 */ shader_hw_mnxn, + /* WINED3DSIH_M3x3 */ shader_hw_mnxn, + /* WINED3DSIH_M3x4 */ shader_hw_mnxn, + /* WINED3DSIH_M4x3 */ shader_hw_mnxn, + /* WINED3DSIH_M4x4 */ shader_hw_mnxn, + /* WINED3DSIH_MAD */ shader_hw_map2gl, + /* WINED3DSIH_MAX */ shader_hw_map2gl, + /* WINED3DSIH_MIN */ shader_hw_map2gl, + /* WINED3DSIH_MOV */ shader_hw_mov, + /* WINED3DSIH_MOVA */ shader_hw_mov, + /* WINED3DSIH_MOVC */ NULL, + /* WINED3DSIH_MUL */ shader_hw_map2gl, + /* WINED3DSIH_NE */ NULL, + /* WINED3DSIH_NOP */ shader_hw_nop, + /* WINED3DSIH_NOT */ NULL, + /* WINED3DSIH_NRM */ shader_hw_nrm, + /* WINED3DSIH_OR */ NULL, + /* WINED3DSIH_PHASE */ shader_hw_nop, + /* WINED3DSIH_POW */ shader_hw_pow, + /* WINED3DSIH_RCP */ shader_hw_scalar_op, + /* WINED3DSIH_REP */ shader_hw_rep, + /* WINED3DSIH_RESINFO */ NULL, + /* WINED3DSIH_RET */ shader_hw_ret, + /* WINED3DSIH_RETP */ NULL, + /* WINED3DSIH_ROUND_NE */ NULL, + /* WINED3DSIH_ROUND_NI */ NULL, + /* WINED3DSIH_ROUND_PI */ NULL, + /* WINED3DSIH_ROUND_Z */ NULL, + /* WINED3DSIH_RSQ */ shader_hw_scalar_op, + /* WINED3DSIH_SAMPLE */ NULL, + /* WINED3DSIH_SAMPLE_B */ NULL, + /* WINED3DSIH_SAMPLE_C */ NULL, + /* WINED3DSIH_SAMPLE_C_LZ */ NULL, + /* WINED3DSIH_SAMPLE_GRAD */ NULL, + /* WINED3DSIH_SAMPLE_INFO */ NULL, + /* WINED3DSIH_SAMPLE_LOD */ NULL, + /* WINED3DSIH_SAMPLE_POS */ NULL, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_hw_map2gl, + /* WINED3DSIH_SGN */ shader_hw_sgn, + /* WINED3DSIH_SINCOS */ shader_hw_sincos, + /* WINED3DSIH_SLT */ shader_hw_map2gl, + /* WINED3DSIH_SQRT */ NULL, + /* WINED3DSIH_STORE_RAW */ NULL, + /* WINED3DSIH_STORE_STRUCTURED */ NULL, + /* WINED3DSIH_STORE_UAV_TYPED */ NULL, + /* WINED3DSIH_SUB */ shader_hw_map2gl, + /* WINED3DSIH_SWAPC */ NULL, + /* WINED3DSIH_SWITCH */ NULL, + /* WINED3DSIH_SYNC */ NULL, + /* WINED3DSIH_TEX */ pshader_hw_tex, + /* WINED3DSIH_TEXBEM */ pshader_hw_texbem, + /* WINED3DSIH_TEXBEML */ pshader_hw_texbem, + /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord, + /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth, + /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3, + /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex, + /* WINED3DSIH_TEXKILL */ pshader_hw_texkill, + /* WINED3DSIH_TEXLDD */ shader_hw_texldd, + /* WINED3DSIH_TEXLDL */ shader_hw_texldl, + /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb, + /* WINED3DSIH_UBFE */ NULL, + /* WINED3DSIH_UDIV */ NULL, + /* WINED3DSIH_UGE */ NULL, + /* WINED3DSIH_ULT */ NULL, + /* WINED3DSIH_UMAX */ NULL, + /* WINED3DSIH_UMIN */ NULL, + /* WINED3DSIH_UMUL */ NULL, + /* WINED3DSIH_USHR */ NULL, + /* WINED3DSIH_UTOF */ NULL, + /* WINED3DSIH_XOR */ NULL, }; static BOOL get_bool_const(const struct wined3d_shader_instruction *ins, @@ -5456,8 +5363,7 @@ static void record_instruction(struct list *list, const struct wined3d_shader_in } rec->ins.dst = dst_param; - src_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*src_param) * ins->src_count); - if (!src_param) + if (!(src_param = wined3d_calloc(ins->src_count, sizeof(*src_param)))) goto free; for (i = 0; i < ins->src_count; ++i) { @@ -5760,13 +5666,15 @@ static BOOL shader_arb_has_ffp_proj_control(void *shader_priv) return priv->ffp_proj_control; } +static void shader_arb_precompile(void *shader_priv, struct wined3d_shader *shader) {} + const struct wined3d_shader_backend_ops arb_program_shader_backend = { shader_arb_handle_instruction, + shader_arb_precompile, shader_arb_select, + shader_arb_select_compute, shader_arb_disable, - shader_arb_select_depth_blt, - shader_arb_deselect_depth_blt, shader_arb_update_float_vertex_constants, shader_arb_update_float_pixel_constants, shader_arb_load_constants, @@ -5889,8 +5797,8 @@ static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen /* TODO: Implement WINED3DTEXOPCAPS_PREMODULATE */ - caps->MaxTextureBlendStages = 8; - caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); + caps->MaxTextureBlendStages = MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_TEXTURES); } static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) @@ -5901,43 +5809,73 @@ static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) static void state_texfactor_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_device *device = context->device; + struct wined3d_color color; - /* Don't load the parameter if we're using an arbfp pixel shader, - * otherwise we'll overwrite application provided constants. */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; - if (use_ps(state)) return; + /* Don't load the parameter if we're using an arbfp pixel shader, + * otherwise we'll overwrite application provided constants. */ + if (use_ps(state)) + return; priv = device->shader_priv; priv->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1; priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1); } - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); - GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col)); - checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col)"); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, &color.r)); + checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, &color.r)"); +} + +static void state_tss_constant_arbfp(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; + struct wined3d_color color; + + if (device->shader_backend == &arb_program_shader_backend) + { + struct shader_arb_priv *priv; + + /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite + * application provided constants. + */ + if (use_ps(state)) + return; + + priv = device->shader_priv; + priv->pshader_const_dirty[ARB_FFP_CONST_CONSTANT(stage)] = 1; + priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_CONSTANT(stage) + 1); + } + + wined3d_color_from_d3dcolor(&color, state->texture_states[stage][WINED3D_TSS_CONSTANT]); + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_CONSTANT(stage), &color.r)); + checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_CONSTANT(stage), &color.r)"); } static void state_arb_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float col[4]; - /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite - * application provided constants - */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; - if (use_ps(state)) return; + /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite + * application provided constants. + */ + if (use_ps(state)) + return; priv = device->shader_priv; priv->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1; @@ -5960,8 +5898,8 @@ static void state_arb_specularenable(struct wined3d_context *context, static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float mat[2][2]; context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV; @@ -5991,8 +5929,8 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float param[4]; context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV; @@ -6001,7 +5939,7 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, { struct shader_arb_priv *priv = device->shader_priv; - /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants. */ + /* Exit now, don't set the luminance below, otherwise we may overwrite pixel shader constants. */ if (use_ps(state)) return; @@ -6050,20 +5988,20 @@ static void alpha_test_arbfp(struct wined3d_context *context, const struct wined static void color_key_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_color float_key[2]; const struct wined3d_texture *texture = state->textures[0]; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; + struct wined3d_color float_key[2]; if (!texture) return; - /* Don't load the parameter if we're using an arbfp pixel shader, - * otherwise we'll overwrite application provided constants. */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; + /* Don't load the parameter if we're using an arbfp pixel shader, + * otherwise we'll overwrite application provided constants. */ if (use_ps(state)) return; @@ -6119,7 +6057,6 @@ static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum ret = "tempreg"; break; case WINED3DTA_CONSTANT: - FIXME("Implement perstage constants\n"); switch(stage) { case 0: ret = "const0"; break; case 1: ret = "const1"; break; @@ -6303,21 +6240,17 @@ static const char *arbfp_texture_target(enum wined3d_gl_resource_type type) static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, const struct wined3d_gl_info *gl_info) { - unsigned int stage; - struct wined3d_string_buffer buffer; - BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; - BOOL bump_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; - BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; - UINT lowest_disabled_stage; - const char *textype; - const char *instr; - char colorcor_dst[8]; - GLuint ret; - DWORD arg0, arg1, arg2; + BYTE tex_read = 0, bump_used = 0, luminance_used = 0, constant_used = 0; BOOL tempreg_used = FALSE, tfactor_used = FALSE; - BOOL op_equal; - BOOL custom_linear_fog = FALSE; + unsigned int stage, lowest_disabled_stage; + struct wined3d_string_buffer buffer; struct color_fixup_masks masks; + BOOL custom_linear_fog = FALSE; + const char *textype, *instr; + DWORD arg0, arg1, arg2; + char colorcor_dst[8]; + BOOL op_equal; + GLuint ret; if (!string_buffer_init(&buffer)) { @@ -6331,7 +6264,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con { shader_addline(&buffer, "PARAM color_key_low = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY_LOW); shader_addline(&buffer, "PARAM color_key_high = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY_HIGH); - tex_read[0] = TRUE; + tex_read |= 1; } /* Find out which textures are read */ @@ -6339,57 +6272,58 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con { if (settings->op[stage].cop == WINED3D_TOP_DISABLE) break; + arg0 = settings->op[stage].carg0 & WINED3DTA_SELECTMASK; arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK; arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK; - if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if (settings->op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA) - tex_read[stage] = TRUE; - if (settings->op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM) - tex_read[stage] = TRUE; - if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP) - { - bump_used[stage] = TRUE; - tex_read[stage] = TRUE; - } - if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE) - { - bump_used[stage] = TRUE; - tex_read[stage] = TRUE; - luminance_used[stage] = TRUE; - } - else if (settings->op[stage].cop == WINED3D_TOP_BLEND_FACTOR_ALPHA) - { - tfactor_used = TRUE; - } - - if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) { - tfactor_used = TRUE; - } - - if(settings->op[stage].dst == tempreg) tempreg_used = TRUE; - if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) { + if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE) + tex_read |= 1u << stage; + if (settings->op[stage].dst == tempreg) tempreg_used = TRUE; + if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) + tempreg_used = TRUE; + if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) + tfactor_used = TRUE; + if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) + constant_used |= 1u << stage; + + switch (settings->op[stage].cop) + { + case WINED3D_TOP_BUMPENVMAP_LUMINANCE: + luminance_used |= 1u << stage; + /* fall through */ + case WINED3D_TOP_BUMPENVMAP: + bump_used |= 1u << stage; + /* fall through */ + case WINED3D_TOP_BLEND_TEXTURE_ALPHA: + case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM: + tex_read |= 1u << stage; + break; + + case WINED3D_TOP_BLEND_FACTOR_ALPHA: + tfactor_used = TRUE; + break; + + default: + break; } if (settings->op[stage].aop == WINED3D_TOP_DISABLE) continue; + arg0 = settings->op[stage].aarg0 & WINED3DTA_SELECTMASK; arg1 = settings->op[stage].aarg1 & WINED3DTA_SELECTMASK; arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK; - if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) { + if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE) + tex_read |= 1u << stage; + if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; - } - if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) { + if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) tfactor_used = TRUE; - } + if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) + constant_used |= 1u << stage; } lowest_disabled_stage = stage; @@ -6413,21 +6347,30 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "PARAM const = {1, 2, 4, 0.5};\n"); shader_addline(&buffer, "TEMP TMP;\n"); shader_addline(&buffer, "TEMP ret;\n"); - if(tempreg_used || settings->sRGB_write) shader_addline(&buffer, "TEMP tempreg;\n"); + if (tempreg_used || settings->sRGB_write) shader_addline(&buffer, "TEMP tempreg;\n"); shader_addline(&buffer, "TEMP arg0;\n"); shader_addline(&buffer, "TEMP arg1;\n"); shader_addline(&buffer, "TEMP arg2;\n"); - for(stage = 0; stage < MAX_TEXTURES; stage++) { - if(!tex_read[stage]) continue; + for (stage = 0; stage < MAX_TEXTURES; ++stage) + { + if (constant_used & (1u << stage)) + shader_addline(&buffer, "PARAM const%u = program.env[%u];\n", stage, ARB_FFP_CONST_CONSTANT(stage)); + + if (!(tex_read & (1u << stage))) + continue; + shader_addline(&buffer, "TEMP tex%u;\n", stage); - if(!bump_used[stage]) continue; + + if (!(bump_used & (1u << stage))) + continue; shader_addline(&buffer, "PARAM bumpmat%u = program.env[%u];\n", stage, ARB_FFP_CONST_BUMPMAT(stage)); - if(!luminance_used[stage]) continue; + + if (!(luminance_used & (1u << stage))) + continue; shader_addline(&buffer, "PARAM luminance%u = program.env[%u];\n", stage, ARB_FFP_CONST_LUMINANCE(stage)); } - if(tfactor_used) { + if (tfactor_used) shader_addline(&buffer, "PARAM tfactor = program.env[%u];\n", ARB_FFP_CONST_TFACTOR); - } shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE); if (settings->sRGB_write) @@ -6449,7 +6392,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con /* Generate texture sampling instructions */ for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) { - if (!tex_read[stage]) + if (!(tex_read & (1u << stage))) continue; textype = arbfp_texture_target(settings->op[stage].tex_type); @@ -6600,8 +6543,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con static void fragment_prog_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_device *device = context->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(state); struct ffp_frag_settings settings; @@ -6619,6 +6562,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi for (i = 0; i < MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); + state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); } state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); @@ -6637,7 +6581,8 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi * settings, then activate it. */ gen_ffp_frag_op(context, state, &settings, FALSE); desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings); - if(!desc) { + if (!desc) + { struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc)); if (!new_desc) { @@ -6667,9 +6612,11 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi for (i = 0; i < MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); + state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); } state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); + color_key_arbfp(context, state, STATE_COLOR_KEY); } context->last_was_pshader = FALSE; } @@ -6874,14 +6821,22 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_arb_specularenable}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, @@ -6918,7 +6873,7 @@ struct arbfp_blit_type struct arbfp_blit_desc { - GLenum shader; + GLuint shader; struct arbfp_blit_type type; struct wine_rb_entry entry; }; @@ -6927,8 +6882,9 @@ struct arbfp_blit_desc #define ARBFP_BLIT_PARAM_COLOR_KEY_LOW 1 #define ARBFP_BLIT_PARAM_COLOR_KEY_HIGH 2 -struct arbfp_blit_priv +struct wined3d_arbfp_blitter { + struct wined3d_blitter blitter; struct wine_rb_tree shaders; GLuint palette_texture; }; @@ -6942,44 +6898,39 @@ static int arbfp_blit_type_compare(const void *key, const struct wine_rb_entry * } /* Context activation is done by the caller. */ -static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *context) +static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *ctx) { - const struct wined3d_gl_info *gl_info = context; struct arbfp_blit_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + context = ctx; + gl_info = context->gl_info; GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader)); checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)"); HeapFree(GetProcessHeap(), 0, entry_arb); } -static HRESULT arbfp_blit_alloc(struct wined3d_device *device) -{ - struct arbfp_blit_priv *priv; - - if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv)))) - return E_OUTOFMEMORY; - - wine_rb_init(&priv->shaders, arbfp_blit_type_compare); - - device->blit_priv = priv; - - return WINED3D_OK; -} - /* Context activation is done by the caller. */ -static void arbfp_blit_free(struct wined3d_device *device) +static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct arbfp_blit_priv *priv = device->blit_priv; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_arbfp_blitter *arbfp_blitter; + struct wined3d_blitter *next; - wine_rb_destroy(&priv->shaders, arbfp_free_blit_shader, &device->adapter->gl_info); + if ((next = blitter->next)) + next->ops->blitter_destroy(next, context); + + arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); + + wine_rb_destroy(&arbfp_blitter->shaders, arbfp_free_blit_shader, context); checkGLcall("Delete blit programs"); - if (priv->palette_texture) - gl_info->gl_ops.gl.p_glDeleteTextures(1, &priv->palette_texture); + if (arbfp_blitter->palette_texture) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &arbfp_blitter->palette_texture); - HeapFree(GetProcessHeap(), 0, device->blit_priv); - device->blit_priv = NULL; + HeapFree(GetProcessHeap(), 0, arbfp_blitter); } static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type, @@ -7111,7 +7062,7 @@ static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arb * | 0.5 | 0.5 | * * So it appears as if there are 4 chroma images, but in fact the odd rows - * in the chroma images are in the same row as the even ones. So its is + * in the chroma images are in the same row as the even ones. So it is * kinda tricky to read * * When reading from rectangle textures, keep in mind that the input y coordinates @@ -7356,10 +7307,9 @@ static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arb } /* Context activation is done by the caller. */ -static GLuint gen_p8_shader(struct arbfp_blit_priv *priv, - const struct wined3d_gl_info *gl_info, const struct arbfp_blit_type *type) +static GLuint gen_p8_shader(const struct wined3d_gl_info *gl_info, const struct arbfp_blit_type *type) { - GLenum shader; + GLuint shader; struct wined3d_string_buffer buffer; const char *tex_target = arbfp_texture_target(type->res_type); @@ -7407,18 +7357,17 @@ static GLuint gen_p8_shader(struct arbfp_blit_priv *priv, } /* Context activation is done by the caller. */ -static void upload_palette(const struct wined3d_texture *texture, struct wined3d_context *context) +static void upload_palette(struct wined3d_arbfp_blitter *blitter, + const struct wined3d_texture *texture, struct wined3d_context *context) { const struct wined3d_palette *palette = texture->swapchain ? texture->swapchain->palette : NULL; - struct wined3d_device *device = texture->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; - struct arbfp_blit_priv *priv = device->blit_priv; - if (!priv->palette_texture) - gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture); + if (!blitter->palette_texture) + gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture); GL_EXTCALL(glActiveTexture(GL_TEXTURE1)); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, priv->palette_texture); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture); gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); @@ -7445,10 +7394,9 @@ static void upload_palette(const struct wined3d_texture *texture, struct wined3d } /* Context activation is done by the caller. */ -static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_gl_info *gl_info, - const struct arbfp_blit_type *type) +static GLuint gen_yuv_shader(const struct wined3d_gl_info *gl_info, const struct arbfp_blit_type *type) { - GLenum shader; + GLuint shader; struct wined3d_string_buffer buffer; char luminance_component; @@ -7570,10 +7518,9 @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_ } /* Context activation is done by the caller. */ -static GLuint arbfp_gen_plain_shader(struct arbfp_blit_priv *priv, - const struct wined3d_gl_info *gl_info, const struct arbfp_blit_type *type) +static GLuint arbfp_gen_plain_shader(const struct wined3d_gl_info *gl_info, const struct arbfp_blit_type *type) { - GLenum shader; + GLuint shader; struct wined3d_string_buffer buffer; const char *tex_target = arbfp_texture_target(type->res_type); @@ -7624,26 +7571,30 @@ static GLuint arbfp_gen_plain_shader(struct arbfp_blit_priv *priv, } /* Context activation is done by the caller. */ -static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface, - const struct wined3d_color_key *color_key) +static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context *context, + const struct wined3d_surface *surface, const struct wined3d_color_key *color_key) { - GLenum shader; - float size[4] = {(float) surface->pow2Width, (float) surface->pow2Height, 1.0f, 1.0f}; - struct arbfp_blit_priv *priv = blit_priv; + const struct wined3d_texture *texture = surface->container; enum complex_fixup fixup; const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum gl_texture_type = surface->container->target; struct wine_rb_entry *entry; struct arbfp_blit_type type; struct arbfp_blit_desc *desc; struct wined3d_color float_color_key[2]; + struct wined3d_vec4 size; + GLuint shader; - if (is_complex_fixup(surface->resource.format->color_fixup)) - fixup = get_complex_fixup(surface->resource.format->color_fixup); + size.x = wined3d_texture_get_level_pow2_width(texture, surface->texture_level); + size.y = wined3d_texture_get_level_pow2_height(texture, surface->texture_level); + size.z = 1.0f; + size.w = 1.0f; + + if (is_complex_fixup(texture->resource.format->color_fixup)) + fixup = get_complex_fixup(texture->resource.format->color_fixup); else fixup = COMPLEX_FIXUP_NONE; - switch (gl_texture_type) + switch (texture->target) { case GL_TEXTURE_1D: type.res_type = WINED3D_GL_RES_TYPE_TEX_1D; @@ -7666,15 +7617,14 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, break; default: - ERR("Unexpected GL texture type %x.\n", gl_texture_type); + ERR("Unexpected GL texture type %#x.\n", texture->target); type.res_type = WINED3D_GL_RES_TYPE_TEX_2D; } type.fixup = fixup; type.use_color_key = !!color_key; type.padding = 0; - entry = wine_rb_get(&priv->shaders, &type); - if (entry) + if ((entry = wine_rb_get(&blitter->shaders, &type))) { desc = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); shader = desc->shader; @@ -7684,20 +7634,20 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, switch (fixup) { case COMPLEX_FIXUP_NONE: - if (!is_identity_fixup(surface->resource.format->color_fixup)) + if (!is_identity_fixup(texture->resource.format->color_fixup)) FIXME("Implement support for sign or swizzle fixups.\n"); - shader = arbfp_gen_plain_shader(priv, gl_info, &type); + shader = arbfp_gen_plain_shader(gl_info, &type); break; case COMPLEX_FIXUP_P8: - shader = gen_p8_shader(priv, gl_info, &type); + shader = gen_p8_shader(gl_info, &type); break; case COMPLEX_FIXUP_YUY2: case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YV12: case COMPLEX_FIXUP_NV12: - shader = gen_yuv_shader(priv, gl_info, &type); + shader = gen_yuv_shader(gl_info, &type); break; } @@ -7713,7 +7663,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, desc->type = type; desc->shader = shader; - if (wine_rb_put(&priv->shaders, &desc->type, &desc->entry) == -1) + if (wine_rb_put(&blitter->shaders, &desc->type, &desc->entry) == -1) { err_out: ERR("Out of memory\n"); @@ -7727,17 +7677,17 @@ err_out: } if (fixup == COMPLEX_FIXUP_P8) - upload_palette(surface->container, context); + upload_palette(blitter, texture, context); gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)); checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)"); - GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARBFP_BLIT_PARAM_SIZE, size)); + GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARBFP_BLIT_PARAM_SIZE, &size.x)); checkGLcall("glProgramLocalParameter4fvARB"); if (type.use_color_key) { - wined3d_format_get_float_color_key(surface->resource.format, color_key, float_color_key); + wined3d_format_get_float_color_key(texture->resource.format, color_key, float_color_key); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARBFP_BLIT_PARAM_COLOR_KEY_LOW, &float_color_key[0].r)); GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, @@ -7757,10 +7707,11 @@ static void arbfp_blit_unset(const struct wined3d_gl_info *gl_info) static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) + enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location, + enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location) { enum complex_fixup src_fixup; + BOOL decompress; if (!gl_info->supported[ARB_FRAGMENT_PROGRAM]) return FALSE; @@ -7783,7 +7734,9 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, return FALSE; } - if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM) + decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); + if (!decompress && (dst_pool == WINED3D_POOL_SYSTEM_MEM || src_pool == WINED3D_POOL_SYSTEM_MEM)) return FALSE; src_fixup = get_complex_fixup(src_format->color_fixup); @@ -7793,7 +7746,8 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, dump_color_fixup_desc(src_format->color_fixup); } - if (!is_identity_fixup(dst_format->color_fixup)) + if (!is_identity_fixup(dst_format->color_fixup) + && (dst_format->id != src_format->id || dst_location != WINED3D_LOCATION_DRAWABLE)) { TRACE("Destination fixups are not supported\n"); return FALSE; @@ -7808,6 +7762,12 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, /* We only support YUV conversions. */ if (!is_complex_fixup(src_format->color_fixup)) { + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + { + WARN("Claiming fixup support because of ORM_BACKBUFFER.\n"); + return TRUE; + } + TRACE("[FAILED]\n"); return FALSE; } @@ -7829,28 +7789,37 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, } } -static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op, DWORD filter, - struct wined3d_surface *src_surface, const RECT *src_rect_in, - struct wined3d_surface *dst_surface, const RECT *dst_rect_in, - const struct wined3d_color_key *color_key) +static void arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { - struct wined3d_context *context; - RECT src_rect = *src_rect_in; - RECT dst_rect = *dst_rect_in; + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_device *device = dst_texture->resource.device; + struct wined3d_arbfp_blitter *arbfp_blitter; struct wined3d_color_key alpha_test_key; + struct wined3d_blitter *next; + RECT s, d; - /* Activate the destination context, set it up for blitting */ - context = context_acquire(device, dst_surface); + if (!arbfp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op, + src_texture->resource.pool, src_texture->resource.format, src_location, + dst_texture->resource.pool, dst_texture->resource.format, dst_location)) + { + if ((next = blitter->next)) + next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, color_key, filter); + return; + } + + arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter); /* Now load the surface */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -#if defined(STAGING_CSMT) - && (src_surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) -#else /* STAGING_CSMT */ - && (src_surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) -#endif /* STAGING_CSMT */ + && (surface_get_sub_resource(src_surface)->locations + & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE - && !wined3d_resource_is_offscreen(&src_surface->container->resource)) + && !wined3d_resource_is_offscreen(&src_texture->resource)) { /* Without FBO blits transferring from the drawable to the texture is * expensive, because we have to flip the data in sysmem. Since we can @@ -7859,79 +7828,105 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_ * rectangle instead. */ surface_load_fb_texture(src_surface, FALSE, context); - src_rect.top = src_surface->resource.height - src_rect.top; - src_rect.bottom = src_surface->resource.height - src_rect.bottom; + s = *src_rect; + s.top = wined3d_texture_get_level_height(src_texture, src_surface->texture_level) - s.top; + s.bottom = wined3d_texture_get_level_height(src_texture, src_surface->texture_level) - s.bottom; + src_rect = &s; } else - wined3d_texture_load(src_surface->container, context, FALSE); + wined3d_texture_load(src_texture, context, FALSE); context_apply_blit_state(context, device); - if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) - surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect); + if (dst_location == WINED3D_LOCATION_DRAWABLE) + { + d = *dst_rect; + surface_translate_drawable_coords(dst_surface, context->win_handle, &d); + dst_rect = &d; + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + GLenum buffer; + + if (dst_location == WINED3D_LOCATION_DRAWABLE) + { + TRACE("Destination surface %p is onscreen.\n", dst_surface); + buffer = wined3d_texture_get_gl_buffer(dst_texture); + } + else + { + TRACE("Destination surface %p is offscreen.\n", dst_surface); + buffer = GL_COLOR_ATTACHMENT0; + } + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); + context_set_draw_buffer(context, buffer); + context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); + } if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) { - const struct wined3d_format *fmt = src_surface->resource.format; + const struct wined3d_format *fmt = src_texture->resource.format; alpha_test_key.color_space_low_value = 0; alpha_test_key.color_space_high_value = ~(((1u << fmt->alpha_size) - 1) << fmt->alpha_offset); color_key = &alpha_test_key; } - arbfp_blit_set(device->blit_priv, context, src_surface, color_key); + arbfp_blit_set(arbfp_blitter, context, src_surface, color_key); /* Draw a textured quad */ - draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter); + draw_textured_quad(src_surface, context, src_rect, dst_rect, filter); /* Leave the opengl state valid for blitting */ arbfp_blit_unset(context->gl_info); -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - context->gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering - || (dst_surface->container->swapchain - && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) - context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); - - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); -#else /* STAGING_CSMT */ if (wined3d_settings.strict_draw_ordering - || (dst_surface->container->swapchain - && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) + || (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))) context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); - - surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); - surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); -#endif /* STAGING_CSMT */ } -static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) +static void arbfp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil) { - FIXME("Color filling not implemented by arbfp_blit\n"); - return WINED3DERR_INVALIDCALL; + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_clear(next, device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); } -static HRESULT arbfp_blit_depth_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, - const RECT *rect, float depth) +static const struct wined3d_blitter_ops arbfp_blitter_ops = { - FIXME("Depth filling not implemented by arbfp_blit.\n"); - return WINED3DERR_INVALIDCALL; -} - -const struct blit_shader arbfp_blit = { - arbfp_blit_alloc, - arbfp_blit_free, - arbfp_blit_set, - arbfp_blit_unset, - arbfp_blit_supported, - arbfp_blit_color_fill, - arbfp_blit_depth_fill, - arbfp_blit_surface, + arbfp_blitter_destroy, + arbfp_blitter_clear, + arbfp_blitter_blit, }; + +void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, const struct wined3d_device *device) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_arbfp_blitter *blitter; + + if (device->shader_backend != &arb_program_shader_backend + && device->shader_backend != &glsl_shader_backend) + return; + + if (!gl_info->supported[ARB_FRAGMENT_PROGRAM]) + return; + + if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + { + ERR("Failed to allocate blitter.\n"); + return; + } + + TRACE("Created blitter %p.\n", blitter); + + blitter->blitter.ops = &arbfp_blitter_ops; + blitter->blitter.next = *next; + wine_rb_init(&blitter->shaders, arbfp_blit_type_compare); + blitter->palette_texture = 0; + *next = &blitter->blitter; +} diff --git a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c index 5b0cde05ec3..0ba5c5b40b5 100644 --- a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -47,7 +47,7 @@ struct atifs_ffp_desc struct ffp_frag_desc parent; GLuint shader; unsigned int num_textures_used; - enum atifs_constant_value constants[8]; + enum atifs_constant_value constants[MAX_TEXTURES]; }; struct atifs_private_data @@ -932,7 +932,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], constants[ATIFS_CONST_TFACTOR - GL_CON_0_ATI] = ATIFS_CONSTANT_TFACTOR; /* Assign unused constants to avoid reloading due to unused <-> bump matrix switches. */ - for (stage = 0; stage < 8; ++stage) + for (stage = 0; stage < MAX_TEXTURES; ++stage) { if (constants[stage] == ATIFS_CONSTANT_UNUSED) constants[stage] = ATIFS_CONSTANT_BUMP; @@ -947,16 +947,16 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], static void atifs_tfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; + struct wined3d_color color; if (!ctx_priv->last_shader || ctx_priv->last_shader->constants[ATIFS_CONST_TFACTOR - GL_CON_0_ATI] != ATIFS_CONSTANT_TFACTOR) return; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); - GL_EXTCALL(glSetFragmentShaderConstantATI(ATIFS_CONST_TFACTOR, col)); - checkGLcall("glSetFragmentShaderConstantATI(ATIFS_CONST_TFACTOR, col)"); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); + GL_EXTCALL(glSetFragmentShaderConstantATI(ATIFS_CONST_TFACTOR, &color.r)); + checkGLcall("glSetFragmentShaderConstantATI(ATIFS_CONST_TFACTOR, &color.r)"); } static void set_bumpmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -992,21 +992,21 @@ static void atifs_stage_constant(struct wined3d_context *context, const struct w { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; + struct wined3d_color color; if (!ctx_priv->last_shader || ctx_priv->last_shader->constants[stage] != ATIFS_CONSTANT_STAGE) return; - D3DCOLORTOGLFLOAT4(state->texture_states[stage][WINED3D_TSS_CONSTANT], col); - GL_EXTCALL(glSetFragmentShaderConstantATI(ATIFS_CONST_STAGE(stage), col)); - checkGLcall("glSetFragmentShaderConstantATI(ATIFS_CONST_STAGE(stage), col)"); + wined3d_color_from_d3dcolor(&color, state->texture_states[stage][WINED3D_TSS_CONSTANT]); + GL_EXTCALL(glSetFragmentShaderConstantATI(ATIFS_CONST_STAGE(stage), &color.r)); + checkGLcall("glSetFragmentShaderConstantATI(ATIFS_CONST_STAGE(stage), &color.r)"); } static void set_tex_op_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; @@ -1018,7 +1018,8 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined gen_ffp_frag_op(context, state, &settings, TRUE); desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings); - if(!desc) { + if (!desc) + { struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*new_desc)); if (!new_desc) { @@ -1030,13 +1031,13 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined { if (settings.op[i].cop == WINED3D_TOP_DISABLE) break; - new_desc->num_textures_used = i + 1; + ++new_desc->num_textures_used; } new_desc->parent.settings = settings; new_desc->shader = gen_ati_shader(settings.op, gl_info, new_desc->constants); add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent); - TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc); + TRACE("Allocated fixed function replacement shader descriptor %p.\n", new_desc); desc = new_desc; } @@ -1056,7 +1057,7 @@ static void set_tex_op_atifs(struct wined3d_context *context, const struct wined GL_EXTCALL(glBindFragmentShaderATI(desc->shader)); ctx_priv->last_shader = desc; - for (i = 0; i < 8; i++) + for (i = 0; i < MAX_TEXTURES; i++) { if (last_shader && last_shader->constants[i] == desc->constants[i]) continue; @@ -1301,7 +1302,7 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen * The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the * r200 series and use an ARB or GLSL shader instead */ - caps->MaxTextureBlendStages = 8; + caps->MaxTextureBlendStages = MAX_TEXTURES; caps->MaxSimultaneousTextures = 6; } diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index 83a01925138..d8b6263eb30 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -27,54 +27,45 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ -#define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ -#define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ -#if defined(STAGING_CSMT) -#define WINED3D_BUFFER_DISCARD 0x08 /* The next PreLoad may discard the buffer contents. */ -#define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ -#define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ +#define WINED3D_BUFFER_USE_BO 0x02 /* Use a buffer object for this buffer. */ +#define WINED3D_BUFFER_PIN_SYSMEM 0x04 /* Keep a system memory copy for this buffer. */ +#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */ +#define WINED3D_BUFFER_APPLESYNC 0x10 /* Using sync as in GL_APPLE_flush_buffer_range. */ #define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ #define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ -void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) -#else /* STAGING_CSMT */ -#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */ -#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */ -#define WINED3D_BUFFER_SYNC 0x20 /* There has been at least one synchronized map since the last preload. */ -#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */ - -#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ -#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ -#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ -#define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ - -static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) -#endif /* STAGING_CSMT */ +static void wined3d_buffer_evict_sysmem(struct wined3d_buffer *buffer) { - if (!offset && !size) + if (buffer->flags & WINED3D_BUFFER_PIN_SYSMEM) + { + TRACE("Not evicting system memory for buffer %p.\n", buffer); + return; + } + + TRACE("Evicting system memory for buffer %p.\n", buffer); + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_SYSMEM); + wined3d_resource_free_sysmem(&buffer->resource); +} + +static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, unsigned int offset, unsigned int size) +{ + if (!offset && (!size || size == buffer->resource.size)) goto invalidate_all; - if (offset > buffer->resource.size || offset + size > buffer->resource.size) + if (offset > buffer->resource.size || size > buffer->resource.size - offset) { WARN("Invalid range specified, invalidating entire buffer.\n"); goto invalidate_all; } - if (buffer->modified_areas >= buffer->maps_size) + if (!wined3d_array_reserve((void **)&buffer->maps, &buffer->maps_size, + buffer->modified_areas + 1, sizeof(*buffer->maps))) { - struct wined3d_map_range *new; - - if (!(new = HeapReAlloc(GetProcessHeap(), 0, buffer->maps, 2 * buffer->maps_size * sizeof(*buffer->maps)))) - { - ERR("Failed to allocate maps array, invalidating entire buffer.\n"); - goto invalidate_all; - } - - buffer->maps = new; - buffer->maps_size *= 2; + ERR("Failed to allocate maps array, invalidating entire buffer.\n"); + goto invalidate_all; } buffer->maps[buffer->modified_areas].offset = offset; @@ -100,52 +91,120 @@ static BOOL buffer_is_dirty(const struct wined3d_buffer *buffer) static BOOL buffer_is_fully_dirty(const struct wined3d_buffer *buffer) { - unsigned int i; - - for (i = 0; i < buffer->modified_areas; ++i) - { - if (!buffer->maps[i].offset && buffer->maps[i].size == buffer->resource.size) - return TRUE; - } - return FALSE; + return buffer->modified_areas == 1 + && !buffer->maps->offset && buffer->maps->size == buffer->resource.size; } -/* Context activation is done by the caller */ -static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +static void wined3d_buffer_validate_location(struct wined3d_buffer *buffer, DWORD location) { - if(!This->buffer_object) return; + TRACE("buffer %p, location %s.\n", buffer, wined3d_debug_location(location)); - GL_EXTCALL(glDeleteBuffers(1, &This->buffer_object)); - checkGLcall("glDeleteBuffers"); - This->buffer_object = 0; + if (location & WINED3D_LOCATION_BUFFER) + buffer_clear_dirty_areas(buffer); - if(This->query) - { - wined3d_event_query_destroy(This->query); - This->query = NULL; - } - This->flags &= ~WINED3D_BUFFER_APPLESYNC; + buffer->locations |= location; + + TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations)); +} + +static void wined3d_buffer_invalidate_range(struct wined3d_buffer *buffer, DWORD location, + unsigned int offset, unsigned int size) +{ + TRACE("buffer %p, location %s, offset %u, size %u.\n", + buffer, wined3d_debug_location(location), offset, size); + + if (location & WINED3D_LOCATION_BUFFER) + buffer_invalidate_bo_range(buffer, offset, size); + + buffer->locations &= ~location; + + TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations)); + + if (!buffer->locations) + ERR("Buffer %p does not have any up to date location.\n", buffer); +} + +void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) +{ + wined3d_buffer_invalidate_range(buffer, location, 0, 0); } /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) -#else /* STAGING_CSMT */ -static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) -#endif /* STAGING_CSMT */ +static void buffer_bind(struct wined3d_buffer *buffer, struct wined3d_context *context) { - GLenum gl_usage = GL_STATIC_DRAW_ARB; - GLenum error; - const struct wined3d_gl_info *gl_info = context->gl_info; + context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object); +} - TRACE("Creating an OpenGL vertex buffer object for wined3d_buffer %p with usage %s.\n", - This, debug_d3dusage(This->resource.usage)); +/* Context activation is done by the caller. */ +static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_resource *resource = &buffer->resource; + + if (!buffer->buffer_object) + return; + + /* The stream source state handler might have read the memory of the + * vertex buffer already and got the memory in the vbo which is not + * valid any longer. Dirtify the stream source to force a reload. This + * happens only once per changed vertexbuffer and should occur rather + * rarely. */ + if (resource->bind_count) + { + if (buffer->bind_flags & WINED3D_BIND_VERTEX_BUFFER) + device_invalidate_state(resource->device, STATE_STREAMSRC); + if (buffer->bind_flags & WINED3D_BIND_INDEX_BUFFER) + device_invalidate_state(resource->device, STATE_INDEXBUFFER); + if (buffer->bind_flags & WINED3D_BIND_CONSTANT_BUFFER) + { + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX)); + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL)); + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN)); + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY)); + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL)); + device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE)); + } + if (buffer->bind_flags & WINED3D_BIND_STREAM_OUTPUT) + { + device_invalidate_state(resource->device, STATE_STREAM_OUTPUT); + if (context->transform_feedback_active) + { + /* We have to make sure that transform feedback is not active + * when deleting a potentially bound transform feedback buffer. + * This may happen when the device is being destroyed. */ + WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer); + context_end_transform_feedback(context); + } + } + } + + GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object)); + checkGLcall("glDeleteBuffers"); + buffer->buffer_object = 0; + + if (buffer->query) + { + wined3d_event_query_destroy(buffer->query); + buffer->query = NULL; + } + buffer->flags &= ~WINED3D_BUFFER_APPLESYNC; +} + +/* Context activation is done by the caller. */ +static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum gl_usage = GL_STATIC_DRAW; + GLenum error; + + TRACE("Creating an OpenGL buffer object for wined3d_buffer %p with usage %s.\n", + buffer, debug_d3dusage(buffer->resource.usage)); /* Make sure that the gl error is cleared. Do not use checkGLcall - * here because checkGLcall just prints a fixme and continues. However, - * if an error during VBO creation occurs we can fall back to non-vbo operation - * with full functionality(but performance loss) - */ + * here because checkGLcall just prints a fixme and continues. However, + * if an error during VBO creation occurs we can fall back to non-VBO operation + * with full functionality(but performance loss). + */ while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR); /* Basically the FVF parameter passed to CreateVertexBuffer is no good. @@ -154,85 +213,64 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine * to be verified to check if the rhw and color values are in the correct * format. */ - GL_EXTCALL(glGenBuffers(1, &This->buffer_object)); + GL_EXTCALL(glGenBuffers(1, &buffer->buffer_object)); error = gl_info->gl_ops.gl.p_glGetError(); - if (!This->buffer_object || error != GL_NO_ERROR) + if (!buffer->buffer_object || error != GL_NO_ERROR) { - ERR("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error); + ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); + buffer_bind(buffer, context); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { - ERR("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error); + ERR("Failed to bind the BO with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - if (This->resource.usage & WINED3DUSAGE_DYNAMIC) + if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC) { TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n"); gl_usage = GL_STREAM_DRAW_ARB; - if(gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) + if (gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) { - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); -#if !defined(STAGING_CSMT) - This->flags |= WINED3D_BUFFER_FLUSH; - -#endif /* STAGING_CSMT */ - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); - This->flags |= WINED3D_BUFFER_APPLESYNC; + GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); + GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE"); + buffer->flags |= WINED3D_BUFFER_APPLESYNC; } - /* No setup is needed here for GL_ARB_map_buffer_range */ + /* No setup is needed here for GL_ARB_map_buffer_range. */ } - /* Reserve memory for the buffer. The amount of data won't change - * so we are safe with calling glBufferData once and - * calling glBufferSubData on updates. Upload the actual data in case - * we're not double buffering, so we can release the heap mem afterwards - */ - GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage)); + GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, gl_usage)); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { - ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); + ERR("glBufferData failed with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - This->buffer_object_usage = gl_usage; + buffer->buffer_object_usage = gl_usage; + buffer_invalidate_bo_range(buffer, 0, 0); - if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) - buffer_invalidate_bo_range(This, 0, 0); - else -#if defined(STAGING_CSMT) - { - wined3d_resource_free_sysmem(&This->resource); - This->resource.map_heap_memory = NULL; - } -#else /* STAGING_CSMT */ - wined3d_resource_free_sysmem(&This->resource); -#endif /* STAGING_CSMT */ - - return; + return TRUE; fail: - /* Clean up all vbo init, but continue because we can work without a vbo :-) */ - ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n"); - delete_gl_buffer(This, gl_info); - buffer_clear_dirty_areas(This); + /* Clean up all BO init, but continue because we can work without a BO :-) */ + ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n"); + buffer->flags &= ~WINED3D_BUFFER_USE_BO; + buffer_destroy_buffer_object(buffer, context); + buffer_clear_dirty_areas(buffer); + return FALSE; } -static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, +static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer, const enum wined3d_buffer_conversion_type conversion_type, const struct wined3d_stream_info_element *attrib, DWORD *stride_this_run) { - DWORD attrib_size; + const struct wined3d_format *format = attrib->format; BOOL ret = FALSE; unsigned int i; DWORD_PTR data; @@ -244,41 +282,39 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, */ if (!attrib->stride) { - FIXME("%s used with stride 0, let's hope we get the vertex stride from somewhere else\n", - debug_d3dformat(attrib->format->id)); + FIXME("%s used with stride 0, let's hope we get the vertex stride from somewhere else.\n", + debug_d3dformat(format->id)); } - else if(attrib->stride != *stride_this_run && *stride_this_run) + else if (attrib->stride != *stride_this_run && *stride_this_run) { - FIXME("Got two concurrent strides, %d and %d\n", attrib->stride, *stride_this_run); + FIXME("Got two concurrent strides, %d and %d.\n", attrib->stride, *stride_this_run); } else { *stride_this_run = attrib->stride; - if (This->stride != *stride_this_run) + if (buffer->stride != *stride_this_run) { /* We rely that this happens only on the first converted attribute that is found, * if at all. See above check */ - TRACE("Reconverting because converted attributes occur, and the stride changed\n"); - This->stride = *stride_this_run; - HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conversion_map); - This->conversion_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*This->conversion_map) * This->stride); + TRACE("Reconverting because converted attributes occur, and the stride changed.\n"); + buffer->stride = *stride_this_run; + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer->conversion_map); + buffer->conversion_map = wined3d_calloc(buffer->stride, sizeof(*buffer->conversion_map)); ret = TRUE; } } - data = ((DWORD_PTR)attrib->data.addr) % This->stride; - attrib_size = attrib->format->component_count * attrib->format->component_size; - for (i = 0; i < attrib_size; ++i) + data = ((DWORD_PTR)attrib->data.addr) % buffer->stride; + for (i = 0; i < format->attribute_size; ++i) { - DWORD_PTR idx = (data + i) % This->stride; - if (This->conversion_map[idx] != conversion_type) + DWORD_PTR idx = (data + i) % buffer->stride; + if (buffer->conversion_map[idx] != conversion_type) { - TRACE("Byte %ld in vertex changed\n", idx); - TRACE("It was type %d, is %d now\n", This->conversion_map[idx], conversion_type); + TRACE("Byte %lu in vertex changed:\n", idx); + TRACE(" It was type %#x, is %#x now.\n", buffer->conversion_map[idx], conversion_type); ret = TRUE; - This->conversion_map[idx] = conversion_type; + buffer->conversion_map[idx] = conversion_type; } } @@ -405,6 +441,10 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s fixup_flags, &stride_this_run) || ret; fixup_flags &= ~WINED3D_BUFFER_FIXUP_XYZRHW; + ret = buffer_check_attribute(This, si, state, WINED3D_FFP_BLENDWEIGHT, + fixup_flags, &stride_this_run) || ret; + ret = buffer_check_attribute(This, si, state, WINED3D_FFP_BLENDINDICES, + fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, state, WINED3D_FFP_NORMAL, fixup_flags, &stride_this_run) || ret; ret = buffer_check_attribute(This, si, state, WINED3D_FFP_DIFFUSE, @@ -442,77 +482,40 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s return ret; } -static inline void fixup_d3dcolor(DWORD *dst_color) +static inline unsigned int fixup_d3dcolor(DWORD *dst_color) { DWORD src_color = *dst_color; -#if defined(STAGING_CSMT) - /* Color conversion like in draw_strided_slow. watch out for little endianity - * If we want that stuff to work on big endian machines too we have to consider more things + /* Color conversion like in draw_primitive_immediate_mode(). Watch out for + * endianness. If we want this to work on big-endian machines as well we + * have to consider more things. * * 0xff000000: Alpha mask * 0x00ff0000: Blue mask * 0x0000ff00: Green mask * 0x000000ff: Red mask */ -#else /* STAGING_CSMT */ - /* Color conversion like in drawStridedSlow. watch out for little endianity - * If we want that stuff to work on big endian machines too we have to consider more things - * - * 0xff000000: Alpha mask - * 0x00ff0000: Blue mask - * 0x0000ff00: Green mask - * 0x000000ff: Red mask - */ -#endif /* STAGING_CSMT */ *dst_color = 0; *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */ *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */ *dst_color |= (src_color & 0x000000ffu) << 16; /* Blue */ + + return sizeof(*dst_color); } -static inline void fixup_transformed_pos(float *p) +static inline unsigned int fixup_transformed_pos(struct wined3d_vec4 *p) { /* rhw conversion like in position_float4(). */ - if (p[3] != 1.0f && p[3] != 0.0f) + if (p->w != 1.0f && p->w != 0.0f) { - float w = 1.0f / p[3]; - p[0] *= w; - p[1] *= w; - p[2] *= w; - p[3] = w; + float w = 1.0f / p->w; + p->x *= w; + p->y *= w; + p->z *= w; + p->w = w; } -} -/* Context activation is done by the caller. */ -void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, - struct wined3d_bo_address *data) -{ - data->buffer_object = buffer->buffer_object; - if (!buffer->buffer_object) - { -#if defined(STAGING_CSMT) - if ((!buffer->resource.map_count || buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) - && buffer->flags & WINED3D_BUFFER_CREATEBO) -#else /* STAGING_CSMT */ - if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) -#endif /* STAGING_CSMT */ - { - buffer_create_buffer_object(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - if (buffer->buffer_object) - { - data->buffer_object = buffer->buffer_object; - data->addr = NULL; - return; - } - } - data->addr = buffer->resource.heap_memory; - } - else - { - data->addr = NULL; - } + return sizeof(*p); } ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) @@ -525,28 +528,207 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) } /* Context activation is done by the caller. */ -BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) +static void wined3d_buffer_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, + const void *data, unsigned int range_count, const struct wined3d_map_range *ranges) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_map_range *range; + + buffer_bind(buffer, context); + + while (range_count--) + { + range = &ranges[range_count]; + GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, + range->offset, range->size, (BYTE *)data + range->offset)); + } + checkGLcall("glBufferSubData"); +} + +static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + unsigned int i, j, range_idx, start, end, vertex_count; + BYTE *data; + + if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM)) + { + ERR("Failed to load system memory.\n"); + return; + } + buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; + + /* Now for each vertex in the buffer that needs conversion. */ + vertex_count = buffer->resource.size / buffer->stride; + + if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + { + ERR("Out of memory.\n"); + return; + } + + for (range_idx = 0; range_idx < buffer->modified_areas; ++range_idx) + { + start = buffer->maps[range_idx].offset; + end = start + buffer->maps[range_idx].size; + + memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); + for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) + { + for (j = 0; j < buffer->stride;) + { + switch (buffer->conversion_map[j]) + { + case CONV_NONE: + /* Done already */ + j += sizeof(DWORD); + break; + case CONV_D3DCOLOR: + j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); + break; + case CONV_POSITIONT: + j += fixup_transformed_pos((struct wined3d_vec4 *) (data + i * buffer->stride + j)); + break; + default: + FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); + ++j; + } + } + } + } + + wined3d_buffer_upload_ranges(buffer, context, data, buffer->modified_areas, buffer->maps); + + HeapFree(GetProcessHeap(), 0, data); +} + +static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, DWORD location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + if (buffer->resource.heap_memory) + return TRUE; + + if (!wined3d_resource_allocate_sysmem(&buffer->resource)) + { + ERR("Failed to allocate system memory.\n"); + return FALSE; + } + return TRUE; + + case WINED3D_LOCATION_BUFFER: + if (buffer->buffer_object) + return TRUE; + + if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) + { + WARN("Trying to create BO for buffer %p with no WINED3D_BUFFER_USE_BO.\n", buffer); + return FALSE; + } + return buffer_create_buffer_object(buffer, context); + + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + +BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, DWORD location) { const struct wined3d_gl_info *gl_info = context->gl_info; - /* Heap_memory exists if the buffer is double buffered or has no buffer object at all. */ - if (This->resource.heap_memory) - return This->resource.heap_memory; + TRACE("buffer %p, context %p, location %s.\n", + buffer, context, wined3d_debug_location(location)); - if (!wined3d_resource_allocate_sysmem(&This->resource)) - ERR("Failed to allocate system memory.\n"); -#if defined(STAGING_CSMT) - This->resource.heap_memory = This->resource.map_heap_memory; -#endif /* STAGING_CSMT */ + if (buffer->locations & location) + { + TRACE("Location (%#x) is already up to date.\n", location); + return TRUE; + } - if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); + if (!buffer->locations) + { + ERR("Buffer %p does not have any up to date location.\n", buffer); + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_DISCARDED); + return wined3d_buffer_load_location(buffer, context, location); + } - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); - GL_EXTCALL(glGetBufferSubData(This->buffer_type_hint, 0, This->resource.size, This->resource.heap_memory)); - This->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + TRACE("Current buffer location %s.\n", wined3d_debug_location(buffer->locations)); - return This->resource.heap_memory; + if (!wined3d_buffer_prepare_location(buffer, context, location)) + return FALSE; + + if (buffer->locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("Buffer previously discarded, nothing to do.\n"); + wined3d_buffer_validate_location(buffer, location); + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_DISCARDED); + return TRUE; + } + + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + buffer_bind(buffer, context); + GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size, + buffer->resource.heap_memory)); + checkGLcall("buffer download"); + break; + + case WINED3D_LOCATION_BUFFER: + if (!buffer->conversion_map) + wined3d_buffer_upload_ranges(buffer, context, buffer->resource.heap_memory, + buffer->modified_areas, buffer->maps); + else + buffer_conversion_upload(buffer, context); + break; + + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; + } + + wined3d_buffer_validate_location(buffer, location); + if (buffer->resource.heap_memory && location == WINED3D_LOCATION_BUFFER + && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) + wined3d_buffer_evict_sysmem(buffer); + + return TRUE; +} + +/* Context activation is done by the caller. */ +BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + if (wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM)) + buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; + return buffer->resource.heap_memory; +} + +DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, + struct wined3d_bo_address *data, DWORD locations) +{ + TRACE("buffer %p, data %p, locations %s.\n", + buffer, data, wined3d_debug_location(locations)); + + if (locations & WINED3D_LOCATION_BUFFER) + { + data->buffer_object = buffer->buffer_object; + data->addr = NULL; + return WINED3D_LOCATION_BUFFER; + } + if (locations & WINED3D_LOCATION_SYSMEM) + { + data->buffer_object = 0; + data->addr = buffer->resource.heap_memory; + return WINED3D_LOCATION_SYSMEM; + } + + ERR("Unexpected locations %s.\n", wined3d_debug_location(locations)); + data->buffer_object = 0; + data->addr = NULL; + return 0; } static void buffer_unload(struct wined3d_resource *resource) @@ -557,20 +739,13 @@ static void buffer_unload(struct wined3d_resource *resource) if (buffer->buffer_object) { - struct wined3d_device *device = resource->device; struct wined3d_context *context; - context = context_acquire(device, NULL); + context = context_acquire(resource->device, NULL, 0); - /* Download the buffer, but don't permanently enable double buffering */ - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - buffer_get_sysmem(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; - } - - delete_gl_buffer(buffer, context->gl_info); - buffer->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */ + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); + buffer_destroy_buffer_object(buffer, context); buffer_clear_dirty_areas(buffer); context_release(context); @@ -585,16 +760,21 @@ static void buffer_unload(struct wined3d_resource *resource) resource_unload(resource); } -#if defined(STAGING_CSMT) -void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) +static void wined3d_buffer_drop_bo(struct wined3d_buffer *buffer) { + buffer->flags &= ~WINED3D_BUFFER_USE_BO; + buffer_unload(&buffer->resource); +} + +static void wined3d_buffer_destroy_object(void *object) +{ + struct wined3d_buffer *buffer = object; struct wined3d_context *context; - struct wined3d_device *device = buffer->resource.device; if (buffer->buffer_object) { - context = context_acquire(device, NULL); - delete_gl_buffer(buffer, context->gl_info); + context = context_acquire(buffer->resource.device, NULL, 0); + buffer_destroy_buffer_object(buffer, context); context_release(context); HeapFree(GetProcessHeap(), 0, buffer->conversion_map); @@ -612,36 +792,9 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) if (!refcount) { - struct wined3d_device *device = buffer->resource.device; - - resource_cleanup(&buffer->resource); - buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); - wined3d_cs_emit_buffer_cleanup(device->cs, buffer); -#else /* STAGING_CSMT */ -ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) -{ - ULONG refcount = InterlockedDecrement(&buffer->resource.ref); - struct wined3d_context *context; - - TRACE("%p decreasing refcount to %u.\n", buffer, refcount); - - if (!refcount) - { - if (buffer->buffer_object) - { - context = context_acquire(buffer->resource.device, NULL); - delete_gl_buffer(buffer, context->gl_info); - context_release(context); - - HeapFree(GetProcessHeap(), 0, buffer->conversion_map); - } - resource_cleanup(&buffer->resource); - buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); - HeapFree(GetProcessHeap(), 0, buffer->maps); - HeapFree(GetProcessHeap(), 0, buffer); -#endif /* STAGING_CSMT */ + wined3d_cs_destroy_object(buffer->resource.device->cs, wined3d_buffer_destroy_object, buffer); } return refcount; @@ -723,148 +876,39 @@ drop_query: This->flags &= ~WINED3D_BUFFER_APPLESYNC; } -/* The caller provides a GL context */ -static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) -{ -#if defined(STAGING_CSMT) - UINT start, len; - - /* This potentially invalidates the element array buffer binding, but the - * caller always takes care of this. */ - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBuffer"); - - if (flags & WINED3D_BUFFER_DISCARD) - { - GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, GL_STREAM_DRAW)); - checkGLcall("glBufferData"); - } - else if (flags & WINED3D_BUFFER_SYNC && This->flags & WINED3D_BUFFER_APPLESYNC) - { - /* OSX doesn't do non-blocking asynchonous glBufferSubData like Linux drivers do, so we want to set - * GL_BUFFER_SERIALIZED_MODIFY_APPLE to GL_FALSE. Unfortunately ARB_sync and APPLE_fence are pretty - * slow on OSX. Putting the buffer back into synchronized mode for future maps is a lot faster. - * (GeForce 650M, Mavericks). The difference between ARB_sync and normal buffer operation is small - * in the glMapBuffer codepath without CSMT. */ - glFinish(); - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); - This->flags &= ~WINED3D_BUFFER_APPLESYNC; -#else /* STAGING_CSMT */ - BYTE *map; - UINT start, len; - - /* This potentially invalidates the element array buffer binding, but the - * caller always takes care of this. */ - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBuffer"); - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield mapflags; - mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; - if (flags & WINED3D_BUFFER_DISCARD) - mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT; - else if (!(flags & WINED3D_BUFFER_SYNC)) - mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; - map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, - This->resource.size, mapflags)); - checkGLcall("glMapBufferRange"); - } - else - { - if (This->flags & WINED3D_BUFFER_APPLESYNC) - { - DWORD syncflags = 0; - if (flags & WINED3D_BUFFER_DISCARD) - syncflags |= WINED3D_MAP_DISCARD; - else if (!(flags & WINED3D_BUFFER_SYNC)) - syncflags |= WINED3D_MAP_NOOVERWRITE; - buffer_sync_apple(This, syncflags, gl_info); - } - map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY)); - checkGLcall("glMapBuffer"); - } - if (!map) - { - ERR("Failed to map opengl buffer\n"); - return; -#endif /* STAGING_CSMT */ - } - - while (This->modified_areas) - { - This->modified_areas--; - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; - -#if defined(STAGING_CSMT) - GL_EXTCALL(glBufferSubData(This->buffer_type_hint, start, len, (BYTE *)This->resource.heap_memory + start)); - checkGLcall("glBufferSubData"); - } -} - static void buffer_mark_used(struct wined3d_buffer *buffer) -#else /* STAGING_CSMT */ - memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); - checkGLcall("glFlushMappedBufferRange"); - } - else if (This->flags & WINED3D_BUFFER_FLUSH) - { - GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); - checkGLcall("glFlushMappedBufferRangeAPPLE"); - } - } - GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); - checkGLcall("glUnmapBuffer"); -} - -void buffer_mark_used(struct wined3d_buffer *buffer) -#endif /* STAGING_CSMT */ { - buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); + buffer->flags &= ~WINED3D_BUFFER_DISCARD; } /* Context activation is done by the caller. */ -void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, +void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) { - DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); - struct wined3d_device *device = buffer->resource.device; - UINT start, end, len, vertices; - const struct wined3d_gl_info *gl_info; + const struct wined3d_gl_info *gl_info = context->gl_info; BOOL decl_changed = FALSE; - unsigned int i, j; - BYTE *data; TRACE("buffer %p.\n", buffer); -#if !defined(STAGING_CSMT) if (buffer->resource.map_count) { WARN("Buffer is mapped, skipping preload.\n"); return; } -#endif /* STAGING_CSMT */ buffer_mark_used(buffer); - if (!buffer->buffer_object) + /* TODO: Make converting independent from VBOs */ + if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) { - /* TODO: Make converting independent from VBOs */ - if (buffer->flags & WINED3D_BUFFER_CREATEBO) - { - buffer_create_buffer_object(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - } - else - { - /* Not doing any conversion */ - return; - } + /* Not doing any conversion */ + return; + } + + if (!wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_BUFFER)) + { + ERR("Failed to prepare buffer location.\n"); + return; } /* Reading the declaration makes only sense if we have valid state information @@ -875,7 +919,7 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte if (!use_vs(state)) { - if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && !context->d3d_info->ffp_generic_attributes) fixup_flags |= WINED3D_BUFFER_FIXUP_D3DCOLOR; if (!context->d3d_info->xyzrhw) fixup_flags |= WINED3D_BUFFER_FIXUP_XYZRHW; @@ -907,28 +951,14 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte if (buffer->decl_change_count > VB_MAXDECLCHANGES || (buffer->conversion_map && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))) { - FIXME("Too many declaration changes or converting dynamic buffer, stopping converting\n"); - - buffer_unload(&buffer->resource); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - - /* The stream source state handler might have read the memory of - * the vertex buffer already and got the memory in the vbo which - * is not valid any longer. Dirtify the stream source to force a - * reload. This happens only once per changed vertexbuffer and - * should occur rather rarely. */ - device_invalidate_state(device, STATE_STREAMSRC); + FIXME("Too many declaration changes or converting dynamic buffer, stopping converting.\n"); + wined3d_buffer_drop_bo(buffer); return; } /* The declaration changed, reload the whole buffer. */ WARN("Reloading buffer because of a vertex declaration change.\n"); buffer_invalidate_bo_range(buffer, 0, 0); - - /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application - * cleared for unsynchronized updates - */ - flags = 0; } else { @@ -942,10 +972,7 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte if (buffer->full_conversion_count > VB_MAXFULLCONVERSIONS) { FIXME("Too many full buffer conversions, stopping converting.\n"); - buffer_unload(&buffer->resource); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - if (buffer->resource.bind_count) - device_invalidate_state(device, STATE_STREAMSRC); + wined3d_buffer_drop_bo(buffer); return; } } @@ -959,101 +986,8 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte } } - if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - device_invalidate_state(device, STATE_INDEXBUFFER); - - if (!buffer->conversion_map) - { - /* That means that there is nothing to fixup. Just upload from - * buffer->resource.heap_memory directly into the vbo. Do not - * free the system memory copy because drawPrimitive may need it if - * the stride is 0, for instancing emulation, vertex blending - * emulation or shader emulation. */ - TRACE("No conversion needed.\n"); - - /* Nothing to do because we locked directly into the vbo */ - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - return; - } - - buffer_direct_upload(buffer, context->gl_info, flags); - - return; - } - - gl_info = context->gl_info; - - if(!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - buffer_get_sysmem(buffer, context); - } - - /* Now for each vertex in the buffer that needs conversion */ - vertices = buffer->resource.size / buffer->stride; - - data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size); - - while(buffer->modified_areas) - { - buffer->modified_areas--; - start = buffer->maps[buffer->modified_areas].offset; - len = buffer->maps[buffer->modified_areas].size; - end = start + len; - - memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); - for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i) - { - for (j = 0; j < buffer->stride; ++j) - { - switch (buffer->conversion_map[j]) - { - case CONV_NONE: - /* Done already */ - j += 3; - break; - case CONV_D3DCOLOR: - fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); - j += 3; - break; - - case CONV_POSITIONT: - fixup_transformed_pos((float *) (data + i * buffer->stride + j)); - j += 15; - break; - default: - FIXME("Unimplemented conversion %d in shifted conversion\n", buffer->conversion_map[j]); - } - } - } - - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); - checkGLcall("glBindBuffer"); - GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); - checkGLcall("glBufferSubData"); - } - - HeapFree(GetProcessHeap(), 0, data); -} - -void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) -{ -#if defined(STAGING_CSMT) - struct wined3d_device *device = buffer->resource.device; - - if (buffer->resource.map_count) - { - WARN("Buffer is mapped, skipping preload.\n"); - return; - } - - wined3d_cs_emit_buffer_preload(device->cs, buffer); -#else /* STAGING_CSMT */ - struct wined3d_context *context; - context = context_acquire(buffer->resource.device, NULL); - buffer_internal_preload(buffer, context, NULL); - context_release(context); -#endif /* STAGING_CSMT */ + if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER)) + ERR("Failed to load buffer location.\n"); } struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) @@ -1063,100 +997,76 @@ struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffe return &buffer->resource; } -HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags) +static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags) { - LONG count; - BYTE *base; -#if defined(STAGING_CSMT) struct wined3d_device *device = buffer->resource.device; struct wined3d_context *context; + LONG count; + BYTE *base; - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); + TRACE("buffer %p, offset %u, size %u, data %p, flags %#x.\n", buffer, offset, size, data, flags); - /* FIXME: There is a race condition with the same code in - * buffer_internal_preload and buffer_get_memory. - * - * This deals with a race condition concering buffer creation and buffer maps. - * If a VBO is created by the worker thread while the buffer is mapped, outdated - * data may be uploaded, and the BO range is not properly invaliated. Keep in - * mind that a broken application might draw from a buffer before mapping it. - * - * Don't try to solve this by going back to always invalidating changed areas. - * This won't work if we ever want to support glMapBufferRange mapping with - * GL_ARB_buffer_storage in the CS. - * - * Also keep in mind that UnLoad can destroy the VBO, so simply creating it - * on buffer creation won't work either. */ - if (buffer->flags & WINED3D_BUFFER_CREATEBO) - { - wined3d_cs_emit_create_vbo(device->cs, buffer); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - } -#else /* STAGING_CSMT */ - - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); -#endif /* STAGING_CSMT */ - - flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture - * fill rate test seems to depend on this. When we map a buffer with - * GL_MAP_INVALIDATE_BUFFER_BIT, the driver is free to discard the - * previous contents of the buffer. The r600g driver only does this when - * the buffer is currently in use, while the proprietary NVIDIA driver - * appears to do this unconditionally. */ -#if defined(STAGING_CSMT) - if (buffer->ignore_discard) -#else /* STAGING_CSMT */ - if (buffer->flags & WINED3D_BUFFER_DISCARD) -#endif /* STAGING_CSMT */ - flags &= ~WINED3D_MAP_DISCARD; count = ++buffer->resource.map_count; if (buffer->buffer_object) { + unsigned int dirty_offset = offset, dirty_size = size; + /* DISCARD invalidates the entire buffer, regardless of the specified * offset and size. Some applications also depend on the entire buffer * being uploaded in that case. Two such applications are Port Royale * and Darkstar One. */ if (flags & WINED3D_MAP_DISCARD) -#if defined(STAGING_CSMT) - wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, 0, 0); - else if (!(flags & WINED3D_MAP_READONLY)) - wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, offset, size); - - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { + dirty_offset = 0; + dirty_size = 0; + } + + if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD | WINED3D_MAP_READONLY)) + || ((flags & WINED3D_MAP_READONLY) && (buffer->locations & WINED3D_LOCATION_SYSMEM)) + || buffer->flags & WINED3D_BUFFER_PIN_SYSMEM) + { + if (!(buffer->locations & WINED3D_LOCATION_SYSMEM)) + { + context = context_acquire(device, NULL, 0); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + context_release(context); + } + + if (!(flags & WINED3D_MAP_READONLY)) + wined3d_buffer_invalidate_range(buffer, WINED3D_LOCATION_BUFFER, dirty_offset, dirty_size); + } + else + { + const struct wined3d_gl_info *gl_info; + + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + + if (flags & WINED3D_MAP_DISCARD) + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); + else + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); + + if (!(flags & WINED3D_MAP_READONLY)) + buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size); + + if ((flags & WINED3D_MAP_DISCARD) && buffer->resource.heap_memory) + wined3d_buffer_evict_sysmem(buffer); + if (count == 1) { - struct wined3d_device *device = buffer->resource.device; - const struct wined3d_gl_info *gl_info; + buffer_bind(buffer, context); - if (wined3d_settings.cs_multithreaded) - { - FIXME("waiting for cs\n"); - wined3d_cs_emit_glfinish(device->cs); - device->cs->ops->finish(device->cs); - } -#else /* STAGING_CSMT */ - buffer_invalidate_bo_range(buffer, 0, 0); - else if (!(flags & WINED3D_MAP_READONLY)) - buffer_invalidate_bo_range(buffer, offset, size); - - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - if (count == 1) - { - struct wined3d_device *device = buffer->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; -#endif /* STAGING_CSMT */ - - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); + /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 + * multitexture fill rate test seems to depend on this. When + * we map a buffer with GL_MAP_INVALIDATE_BUFFER_BIT, the + * driver is free to discard the previous contents of the + * buffer. The r600g driver only does this when the buffer is + * currently in use, while the proprietary NVIDIA driver + * appears to do this unconditionally. */ + if (buffer->flags & WINED3D_BUFFER_DISCARD) + flags &= ~WINED3D_MAP_DISCARD; if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { @@ -1186,75 +1096,29 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN { /* The extra copy is more expensive than not using VBOs at * all on the Nvidia Linux driver, which is the only driver - * that returns unaligned pointers + * that returns unaligned pointers. */ - TRACE("Dynamic buffer, dropping VBO\n"); - buffer_unload(&buffer->resource); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - if (buffer->resource.bind_count) - device_invalidate_state(device, STATE_STREAMSRC); + TRACE("Dynamic buffer, dropping VBO.\n"); + wined3d_buffer_drop_bo(buffer); } else { - TRACE("Falling back to doublebuffered operation\n"); - buffer_get_sysmem(buffer, context); + TRACE("Falling back to doublebuffered operation.\n"); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; } TRACE("New pointer is %p.\n", buffer->resource.heap_memory); -#if defined(STAGING_CSMT) } - context_release(context); } - } - else if(!wined3d_settings.cs_multithreaded) - { - if (flags & WINED3D_MAP_DISCARD) - { - buffer->flags |= WINED3D_BUFFER_DISCARD; - buffer->ignore_discard = TRUE; - } - else if (!(flags & WINED3D_MAP_NOOVERWRITE)) - buffer->flags |= WINED3D_BUFFER_SYNC; - } - } - if (wined3d_settings.cs_multithreaded && count == 1) - { - BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; - if (flags & WINED3D_MAP_DISCARD && !swvp) - { - if (buffer->resource.access_fence) - { - buffer->ignore_discard = TRUE; - wined3d_resource_allocate_sysmem(&buffer->resource); - wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); - } - } - else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard) - { - wined3d_resource_wait_fence(&buffer->resource); - /* Writing to the (otherwise worker thread controlled) - * flags field is OK here since the wait_fence call made - * sure the buffer is idle. */ - buffer->flags |= WINED3D_BUFFER_SYNC; - } - } - - base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; -#else /* STAGING_CSMT */ - buffer->map_ptr = NULL; - } - context_release(context); - } + context_release(context); } if (flags & WINED3D_MAP_DISCARD) buffer->flags |= WINED3D_BUFFER_DISCARD; - else if (!(flags & WINED3D_MAP_NOOVERWRITE)) - buffer->flags |= WINED3D_BUFFER_SYNC; } base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; -#endif /* STAGING_CSMT */ *data = base + offset; TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); @@ -1263,7 +1127,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN return WINED3D_OK; } -void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) +static void wined3d_buffer_unmap(struct wined3d_buffer *buffer) { ULONG i; @@ -1286,18 +1150,16 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) return; } - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) && buffer->buffer_object) + if (buffer->map_ptr) { struct wined3d_device *device = buffer->resource.device; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - context = context_acquire(device, NULL); + context = context_acquire(device, NULL, 0); gl_info = context->gl_info; - if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); + buffer_bind(buffer, context); if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { @@ -1308,11 +1170,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) checkGLcall("glFlushMappedBufferRange"); } } -#if defined(STAGING_CSMT) else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) -#else /* STAGING_CSMT */ - else if (buffer->flags & WINED3D_BUFFER_FLUSH) -#endif /* STAGING_CSMT */ { for (i = 0; i < buffer->modified_areas; ++i) { @@ -1323,16 +1181,6 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) } GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - context_release(context); - - buffer_clear_dirty_areas(buffer); - buffer->map_ptr = NULL; -#else /* STAGING_CSMT */ if (wined3d_settings.strict_draw_ordering) gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -1340,17 +1188,83 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) buffer_clear_dirty_areas(buffer); buffer->map_ptr = NULL; } - else if (buffer->flags & WINED3D_BUFFER_HASDESC) +} + +HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, + struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) +{ + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; + struct wined3d_context *context; + struct wined3d_device *device; + BYTE *dst_ptr, *src_ptr; + DWORD dst_location; + + buffer_mark_used(dst_buffer); + buffer_mark_used(src_buffer); + + device = dst_buffer->resource.device; + + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + + dst_location = wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations); + dst.addr += dst_offset; + + wined3d_buffer_get_memory(src_buffer, &src, src_buffer->locations); + src.addr += src_offset; + + if (dst.buffer_object && src.buffer_object) { - wined3d_buffer_preload(buffer); -#endif /* STAGING_CSMT */ + if (gl_info->supported[ARB_COPY_BUFFER]) + { + GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src.buffer_object)); + GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst.buffer_object)); + GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + src_offset, dst_offset, size)); + checkGLcall("direct buffer copy"); + } + else + { + src_ptr = context_map_bo_address(context, &src, size, src_buffer->buffer_type_hint, WINED3D_MAP_READONLY); + dst_ptr = context_map_bo_address(context, &dst, size, dst_buffer->buffer_type_hint, 0); + + memcpy(dst_ptr, src_ptr, size); + + context_unmap_bo_address(context, &dst, dst_buffer->buffer_type_hint); + context_unmap_bo_address(context, &src, src_buffer->buffer_type_hint); + } } + else if (!dst.buffer_object && src.buffer_object) + { + buffer_bind(src_buffer, context); + GL_EXTCALL(glGetBufferSubData(src_buffer->buffer_type_hint, src_offset, size, dst.addr)); + checkGLcall("buffer download"); + } + else if (dst.buffer_object && !src.buffer_object) + { + buffer_bind(dst_buffer, context); + GL_EXTCALL(glBufferSubData(dst_buffer->buffer_type_hint, dst_offset, size, src.addr)); + checkGLcall("buffer upload"); + } + else + { + memcpy(dst.addr, src.addr, size); + } + + wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size); + + context_release(context); + return WINED3D_OK; } HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, const struct wined3d_box *box, const void *data) { UINT offset, size; +#if defined(STAGING_CSMT) + DWORD flags = 0; +#endif /* STAGING_CSMT */ HRESULT hr; BYTE *ptr; @@ -1365,7 +1279,14 @@ HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, size = buffer->resource.size; } +#if !defined(STAGING_CSMT) if (FAILED(hr = wined3d_buffer_map(buffer, offset, size, &ptr, 0))) +#else /* STAGING_CSMT */ + if (offset == 0 && size == buffer->resource.size) + flags = WINED3D_MAP_DISCARD; + + if (FAILED(hr = wined3d_buffer_map(buffer, offset, size, &ptr, flags))) +#endif /* STAGING_CSMT */ return hr; memcpy(ptr, data, size); @@ -1384,6 +1305,15 @@ static ULONG buffer_resource_decref(struct wined3d_resource *resource) return wined3d_buffer_decref(buffer_from_resource(resource)); } +static void buffer_resource_preload(struct wined3d_resource *resource) +{ + struct wined3d_context *context; + + context = context_acquire(resource->device, NULL, 0); + wined3d_buffer_load(buffer_from_resource(resource), context, NULL); + context_release(context); +} + static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { @@ -1410,6 +1340,24 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags); } +static HRESULT buffer_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags) +{ + struct wined3d_buffer *buffer = buffer_from_resource(resource); + + if (sub_resource_idx) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return E_INVALIDARG; + } + + info->row_pitch = buffer->desc.byte_width; + info->slice_pitch = buffer->desc.byte_width; + info->size = buffer->resource.size; + + return WINED3D_OK; +} + static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) { if (sub_resource_idx) @@ -1422,46 +1370,58 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou return WINED3D_OK; } -#if defined(STAGING_CSMT) -static void wined3d_buffer_location_invalidated(struct wined3d_resource *resource, DWORD location) -{ - ERR("Not yet implemented.\n"); -} - -/* Context activation is done by the caller. */ -static void wined3d_buffer_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - ERR("Not yet implemented.\n"); -} - -#endif /* STAGING_CSMT */ static const struct wined3d_resource_ops buffer_resource_ops = { buffer_resource_incref, buffer_resource_decref, + buffer_resource_preload, buffer_unload, buffer_resource_sub_resource_map, + buffer_resource_sub_resource_map_info, buffer_resource_sub_resource_unmap, -#if defined(STAGING_CSMT) - wined3d_buffer_location_invalidated, - wined3d_buffer_load_location, -#endif /* STAGING_CSMT */ }; +static GLenum buffer_type_hint_from_bind_flags(const struct wined3d_gl_info *gl_info, + unsigned int bind_flags) +{ + if (bind_flags == WINED3D_BIND_INDEX_BUFFER) + return GL_ELEMENT_ARRAY_BUFFER; + + if (bind_flags & (WINED3D_BIND_SHADER_RESOURCE | WINED3D_BIND_UNORDERED_ACCESS) + && gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) + return GL_TEXTURE_BUFFER; + + if (bind_flags & WINED3D_BIND_CONSTANT_BUFFER) + return GL_UNIFORM_BUFFER; + + if (bind_flags & WINED3D_BIND_STREAM_OUTPUT) + return GL_TRANSFORM_FEEDBACK_BUFFER; + + if (bind_flags & ~(WINED3D_BIND_VERTEX_BUFFER | WINED3D_BIND_INDEX_BUFFER)) + FIXME("Unhandled bind flags %#x.\n", bind_flags); + + return GL_ARRAY_BUFFER; +} + static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, - UINT size, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, GLenum bind_hint, + UINT size, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, unsigned int bind_flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); - HRESULT hr; + const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, usage); BOOL dynamic_buffer_ok; + HRESULT hr; if (!size) { - WARN("Size 0 requested, returning WINED3DERR_INVALIDCALL\n"); - return WINED3DERR_INVALIDCALL; + WARN("Size 0 requested, returning E_INVALIDARG.\n"); + return E_INVALIDARG; + } + + if (bind_flags & WINED3D_BIND_CONSTANT_BUFFER && size & (WINED3D_CONSTANT_BUFFER_ALIGNMENT - 1)) + { + WARN("Size %#x is not suitably aligned for constant buffers.\n", size); + return E_INVALIDARG; } if (data && !data->data) @@ -1474,109 +1434,61 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops); if (FAILED(hr)) { - WARN("Failed to initialize resource, hr %#x\n", hr); + WARN("Failed to initialize resource, hr %#x.\n", hr); return hr; } - buffer->buffer_type_hint = bind_hint; -#if defined(STAGING_CSMT) - buffer->ignore_discard = TRUE; -#endif /* STAGING_CSMT */ + buffer->buffer_type_hint = buffer_type_hint_from_bind_flags(gl_info, bind_flags); + buffer->bind_flags = bind_flags; + buffer->locations = WINED3D_LOCATION_SYSMEM; - TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, - debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); + TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n", + buffer, buffer->resource.size, buffer->resource.usage, + debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory); if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING || pool == WINED3D_POOL_MANAGED) { - /* SWvp always returns the same pointer in buffer maps and retains data in DISCARD maps. - * Keep a system memory copy of the buffer to provide the same behavior to the application. - * Still use a VBO to support OpenGL 3 core contexts. */ - TRACE("Using doublebuffer mode because of software vertex processing\n"); - buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + /* SWvp and managed buffers always return the same pointer in buffer + * maps and retain data in DISCARD maps. Keep a system memory copy of + * the buffer to provide the same behavior to the application. */ + TRACE("Using doublebuffer mode.\n"); + buffer->flags |= WINED3D_BUFFER_PIN_SYSMEM; } + /* Observations show that draw_primitive_immediate_mode() is faster on + * dynamic vertex buffers than converting + draw_primitive_arrays(). + * (Half-Life 2 and others.) */ dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; -#if defined(STAGING_CSMT) - /* Observations show that draw_strided_slow is faster on dynamic VBs than converting + - * drawStridedFast (half-life 2 and others). - * - * Basically converting the vertices in the buffer is quite expensive, and observations - * show that draw_strided_slow is faster than converting + uploading + drawStridedFast. - * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. - */ -#else /* STAGING_CSMT */ - /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + - * drawStridedFast (half-life 2 and others). - * - * Basically converting the vertices in the buffer is quite expensive, and observations - * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. - * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. - */ -#endif /* STAGING_CSMT */ if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) { - TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n"); + TRACE("Not creating a BO because GL_ARB_vertex_buffer is not supported.\n"); } - else if(buffer->resource.pool == WINED3D_POOL_SYSTEM_MEM) + else if (buffer->resource.pool == WINED3D_POOL_SYSTEM_MEM) { - TRACE("Not creating a vbo because the vertex buffer is in system memory\n"); + TRACE("Not creating a BO because the buffer is in system memory.\n"); } - else if(!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) + else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) { - TRACE("Not creating a vbo because the buffer has dynamic usage and no GL support\n"); + TRACE("Not creating a BO because the buffer has dynamic usage and no GL support.\n"); } else { - buffer->flags |= WINED3D_BUFFER_CREATEBO; + buffer->flags |= WINED3D_BUFFER_USE_BO; } -#if defined(STAGING_CSMT) - buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); - if (!buffer->maps) + if (!(buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)))) { - ERR("Out of memory\n"); + ERR("Out of memory.\n"); buffer_unload(&buffer->resource); resource_cleanup(&buffer->resource); + wined3d_resource_wait_idle(&buffer->resource); return E_OUTOFMEMORY; } buffer->maps_size = 1; if (data) - { - if (FAILED(hr = wined3d_buffer_upload_data(buffer, NULL, data->data))) - { - ERR("Failed to upload data, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, buffer->maps); - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - return hr; - } - } - - if (wined3d_settings.cs_multithreaded) - buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; -#else /* STAGING_CSMT */ - if (data) - { - if (FAILED(hr = wined3d_buffer_upload_data(buffer, NULL, data->data))) - { - ERR("Failed to upload data, hr %#x.\n", hr); - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - return hr; - } - } - - buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); - if (!buffer->maps) - { - ERR("Out of memory\n"); - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - return E_OUTOFMEMORY; - } - buffer->maps_size = 1; -#endif /* STAGING_CSMT */ + wined3d_device_update_sub_resource(device, &buffer->resource, + 0, NULL, data->data, data->row_pitch, data->slice_pitch); return WINED3D_OK; } @@ -1586,20 +1498,32 @@ HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct struct wined3d_buffer **buffer) { struct wined3d_buffer *object; + enum wined3d_pool pool; HRESULT hr; - TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p\n", + TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n", device, desc, data, parent, parent_ops, buffer); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - FIXME("Ignoring access flags (pool)\n"); + FIXME("Ignoring access flags (pool).\n"); - hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN, - WINED3D_POOL_MANAGED, GL_ARRAY_BUFFER_ARB, data, parent, parent_ops); - if (FAILED(hr)) + /* Some applications map the whole buffer even if they + * only update a small portion of it. If we pin such a + * buffer into system memory things get very slow as + * we upload the whole buffer even though just parts of + * it changed. Most drivers can handle this case more + * efficient using the OpenGL map functions. Applications + * affected by this problem are Banished and Witcher 3. + */ + if (desc->byte_width > 0x10000) + pool = WINED3D_POOL_DEFAULT; + else + pool = WINED3D_POOL_MANAGED; + + if (FAILED(hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN, + pool, desc->bind_flags, data, parent, parent_ops))) { WARN("Failed to initialize buffer, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -1639,8 +1563,8 @@ HRESULT CDECL wined3d_buffer_create_vb(struct wined3d_device *device, UINT size, return WINED3DERR_OUTOFVIDEOMEMORY; } - hr = buffer_init(object, device, size, usage, WINED3DFMT_VERTEXDATA, - pool, GL_ARRAY_BUFFER_ARB, NULL, parent, parent_ops); + hr = buffer_init(object, device, size, usage, WINED3DFMT_UNKNOWN, + pool, WINED3D_BIND_VERTEX_BUFFER, NULL, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize buffer, hr %#x.\n", hr); @@ -1671,7 +1595,7 @@ HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, } hr = buffer_init(object, device, size, usage | WINED3DUSAGE_STATICDECL, - WINED3DFMT_UNKNOWN, pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL, + WINED3DFMT_UNKNOWN, pool, WINED3D_BIND_INDEX_BUFFER, NULL, parent, parent_ops); if (FAILED(hr)) { @@ -1685,12 +1609,3 @@ HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, return WINED3D_OK; } -#if defined(STAGING_CSMT) - -void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) -{ - wined3d_resource_free_sysmem(&buffer->resource); - buffer->resource.heap_memory = mem; - buffer->flags |= WINED3D_BUFFER_DISCARD; -} -#endif /* STAGING_CSMT */ diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index c876837061e..440f9a31736 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -26,6 +26,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous); #define WINED3D_MAX_FBO_ENTRIES 64 +#define WINED3D_ALL_LAYERS (~0u) static DWORD wined3d_context_tls_idx; @@ -95,143 +96,239 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint fbo) } static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_info, - GLenum fbo_target, DWORD format_flags, GLuint rb) + GLenum fbo_target, DWORD flags, GLuint rb) { - if (format_flags & WINED3DFMT_FLAG_DEPTH) + if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb); checkGLcall("glFramebufferRenderbuffer()"); } - if (format_flags & WINED3DFMT_FLAG_STENCIL) + if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb); checkGLcall("glFramebufferRenderbuffer()"); } } -/* Context activation is done by the caller. */ -static void context_attach_depth_stencil_fbo(struct wined3d_context *context, - GLenum fbo_target, struct wined3d_surface *depth_stencil, DWORD location) +static void context_attach_gl_texture_fbo(struct wined3d_context *context, + GLenum fbo_target, GLenum attachment, const struct wined3d_fbo_resource *resource) { const struct wined3d_gl_info *gl_info = context->gl_info; - TRACE("Attach depth stencil %p\n", depth_stencil); - - if (depth_stencil) + if (!resource) { - DWORD format_flags = depth_stencil->container->resource.format_flags; - - if (depth_stencil->current_renderbuffer) + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment, GL_TEXTURE_2D, 0, 0); + } + else if (resource->layer == WINED3D_ALL_LAYERS) + { + if (!gl_info->fbo_ops.glFramebufferTexture) { - context_attach_depth_stencil_rb(gl_info, fbo_target, - format_flags, depth_stencil->current_renderbuffer->id); - } - else - { - switch (location) - { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - if (format_flags & WINED3DFMT_FLAG_DEPTH) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, - depth_stencil->texture_target, depth_stencil->container->texture_rgb.name, - depth_stencil->texture_level); - checkGLcall("glFramebufferTexture2D()"); - } - - if (format_flags & WINED3DFMT_FLAG_STENCIL) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, - depth_stencil->texture_target, depth_stencil->container->texture_rgb.name, - depth_stencil->texture_level); - checkGLcall("glFramebufferTexture2D()"); - } - break; - - case WINED3D_LOCATION_RB_MULTISAMPLE: - context_attach_depth_stencil_rb(gl_info, fbo_target, - format_flags, depth_stencil->rb_multisample); - break; - - case WINED3D_LOCATION_RB_RESOLVED: - context_attach_depth_stencil_rb(gl_info, fbo_target, - format_flags, depth_stencil->rb_resolved); - break; - - default: - ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location); - break; - } + FIXME("OpenGL implementation doesn't support glFramebufferTexture().\n"); + return; } - if (!(format_flags & WINED3DFMT_FLAG_DEPTH)) + gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment, + resource->object, resource->level); + } + else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY || + resource->target == GL_TEXTURE_3D) + { + if (!gl_info->fbo_ops.glFramebufferTextureLayer) { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); + FIXME("OpenGL implementation doesn't support glFramebufferTextureLayer().\n"); + return; } - if (!(format_flags & WINED3DFMT_FLAG_STENCIL)) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); - } + gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment, + resource->object, resource->level, resource->layer); + } + else if (resource->target == GL_TEXTURE_1D) + { + gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment, + resource->target, resource->object, resource->level); + checkGLcall("glFramebufferTexture1D()"); } else { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment, + resource->target, resource->object, resource->level); + } + checkGLcall("attach texture to fbo"); +} - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); +/* Context activation is done by the caller. */ +static void context_attach_depth_stencil_fbo(struct wined3d_context *context, + GLenum fbo_target, const struct wined3d_fbo_resource *resource, BOOL rb_namespace, + DWORD flags) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (resource->object) + { + TRACE("Attach depth stencil %u.\n", resource->object); + + if (rb_namespace) + { + context_attach_depth_stencil_rb(gl_info, fbo_target, + flags, resource->object); + } + else + { + if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH) + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, resource); + + if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL) + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, resource); + } + + if (!(flags & WINED3D_FBO_ENTRY_FLAG_DEPTH)) + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL); + + if (!(flags & WINED3D_FBO_ENTRY_FLAG_STENCIL)) + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); + } + else + { + TRACE("Attach depth stencil 0.\n"); + + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL); + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); } } /* Context activation is done by the caller. */ static void context_attach_surface_fbo(struct wined3d_context *context, - GLenum fbo_target, DWORD idx, struct wined3d_surface *surface, DWORD location) + GLenum fbo_target, DWORD idx, const struct wined3d_fbo_resource *resource, BOOL rb_namespace) { const struct wined3d_gl_info *gl_info = context->gl_info; - TRACE("Attach surface %p to %u\n", surface, idx); + TRACE("Attach GL object %u to %u.\n", resource->object, idx); - if (surface && surface->resource.format->id != WINED3DFMT_NULL) + if (resource->object) { - BOOL srgb; - switch (location) + if (rb_namespace) { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - srgb = location == WINED3D_LOCATION_TEXTURE_SRGB; - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, - surface->texture_target, surface_get_texture_name(surface, context, srgb), - surface->texture_level); - checkGLcall("glFramebufferTexture2D()"); - break; - - case WINED3D_LOCATION_RB_MULTISAMPLE: - gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, - GL_RENDERBUFFER, surface->rb_multisample); - checkGLcall("glFramebufferRenderbuffer()"); - break; - - case WINED3D_LOCATION_RB_RESOLVED: - gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, - GL_RENDERBUFFER, surface->rb_resolved); - checkGLcall("glFramebufferRenderbuffer()"); - break; - - default: - ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location); - break; + gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx, + GL_RENDERBUFFER, resource->object); + checkGLcall("glFramebufferRenderbuffer()"); + } + else + { + context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, resource); } } else { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); + context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, NULL); + } +} + +static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, GLenum target, + GLenum attachment) +{ + static const struct + { + GLenum target; + GLenum binding; + const char *str; + enum wined3d_gl_extension extension; + } + texture_type[] = + { + {GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2d", WINED3D_GL_EXT_NONE}, + {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE}, + {GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2d-array", EXT_TEXTURE_ARRAY}, + }; + + GLint type, name, samples, width, height, old_texture, level, face, fmt, tex_target; + + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name); + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); + + if (type == GL_RENDERBUFFER) + { + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, name); + gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + if (gl_info->limits.samples > 1) + gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); + else + samples = 1; + gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &fmt); + FIXME(" %s: renderbuffer %d, %dx%d, %d samples, format %#x.\n", + debug_fboattachment(attachment), name, width, height, samples, fmt); + } + else if (type == GL_TEXTURE) + { + const char *tex_type_str; + + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level); + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &face); + + if (face) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &old_texture); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, name); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_WIDTH, &width); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_HEIGHT, &height); + + tex_target = GL_TEXTURE_CUBE_MAP; + tex_type_str = "cube"; + } + else + { + unsigned int i; + + tex_type_str = NULL; + for (i = 0; i < sizeof(texture_type) / sizeof(*texture_type); ++i) + { + if (!gl_info->supported[texture_type[i].extension]) + continue; + + gl_info->gl_ops.gl.p_glGetIntegerv(texture_type[i].binding, &old_texture); + while (gl_info->gl_ops.gl.p_glGetError()); + + gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, name); + if (!gl_info->gl_ops.gl.p_glGetError()) + { + tex_target = texture_type[i].target; + tex_type_str = texture_type[i].str; + break; + } + gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, old_texture); + } + if (!tex_type_str) + { + FIXME("Cannot find type of texture %d.\n", name); + return; + } + + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height); + } + + FIXME(" %s: %s texture %d, %dx%d, format %#x.\n", debug_fboattachment(attachment), + tex_type_str, name, width, height, fmt); + + gl_info->gl_ops.gl.p_glBindTexture(tex_target, old_texture); + checkGLcall("Guess texture type"); + } + else if (type == GL_NONE) + { + FIXME(" %s: NONE.\n", debug_fboattachment(attachment)); + } + else + { + ERR(" %s: Unknown attachment %#x.\n", debug_fboattachment(attachment), type); } } @@ -250,7 +347,6 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ } else { - const struct wined3d_surface *attachment; unsigned int i; FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status); @@ -261,29 +357,12 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ return; } - FIXME("\tColor Location %s (%#x).\n", wined3d_debug_location(context->current_fbo->color_location), - context->current_fbo->color_location); - FIXME("\tDepth Stencil Location %s (%#x).\n", wined3d_debug_location(context->current_fbo->ds_location), - context->current_fbo->ds_location); + context_dump_fbo_attachment(gl_info, target, GL_DEPTH_ATTACHMENT); + context_dump_fbo_attachment(gl_info, target, GL_STENCIL_ATTACHMENT); - /* Dump the FBO attachments */ for (i = 0; i < gl_info->limits.buffers; ++i) - { - attachment = context->current_fbo->render_targets[i]; - if (attachment) - { - FIXME("\tColor attachment %d: (%p) %s %ux%u %u samples.\n", - i, attachment, debug_d3dformat(attachment->resource.format->id), - attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type); - } - } - attachment = context->current_fbo->depth_stencil; - if (attachment) - { - FIXME("\tDepth attachment: (%p) %s %ux%u %u samples.\n", - attachment, debug_d3dformat(attachment->resource.format->id), - attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type); - } + context_dump_fbo_attachment(gl_info, target, GL_COLOR_ATTACHMENT0 + i); + checkGLcall("Dump FBO attachments"); } } @@ -293,26 +372,139 @@ static inline DWORD context_generate_rt_mask(GLenum buffer) return buffer ? (1u << 31) | buffer : 0; } -static inline DWORD context_generate_rt_mask_from_surface(const struct wined3d_surface *target) +static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resource *resource) { - return (1u << 31) | surface_get_gl_buffer(target); + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + return 0; + } + + return (1u << 31) | wined3d_texture_get_gl_buffer(texture_from_resource(resource)); +} + +static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context, + struct wined3d_fbo_entry_key *key, unsigned int idx, struct wined3d_rendertarget_info *render_target, + DWORD location) +{ + unsigned int sub_resource_idx = render_target->sub_resource_idx; + struct wined3d_resource *resource = render_target->resource; + struct wined3d_texture *texture; + + if (!resource || resource->format->id == WINED3DFMT_NULL || resource->type == WINED3D_RTYPE_BUFFER) + { + if (resource && resource->type == WINED3D_RTYPE_BUFFER) + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + key->objects[idx].object = 0; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + return; + } + + if (render_target->gl_view.name) + { + key->objects[idx].object = render_target->gl_view.name; + key->objects[idx].target = render_target->gl_view.target; + key->objects[idx].level = 0; + key->objects[idx].layer = WINED3D_ALL_LAYERS; + return; + } + + texture = wined3d_texture_from_resource(resource); + if (resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + + if (surface->current_renderbuffer) + { + key->objects[idx].object = surface->current_renderbuffer->id; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + key->rb_namespace |= 1 << idx; + return; + } + + key->objects[idx].target = surface->texture_target; + key->objects[idx].level = surface->texture_level; + key->objects[idx].layer = surface->texture_layer; + } + else + { + key->objects[idx].target = texture->target; + key->objects[idx].level = sub_resource_idx % texture->level_count; + key->objects[idx].layer = sub_resource_idx / texture->level_count; + } + if (render_target->layer_count != 1) + key->objects[idx].layer = WINED3D_ALL_LAYERS; + + switch (location) + { + case WINED3D_LOCATION_TEXTURE_RGB: + key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, FALSE); + break; + + case WINED3D_LOCATION_TEXTURE_SRGB: + key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, TRUE); + break; + + case WINED3D_LOCATION_RB_MULTISAMPLE: + key->objects[idx].object = texture->rb_multisample; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + key->rb_namespace |= 1 << idx; + break; + + case WINED3D_LOCATION_RB_RESOLVED: + key->objects[idx].object = texture->rb_resolved; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; + key->rb_namespace |= 1 << idx; + break; + } +} + +static void context_generate_fbo_key(const struct wined3d_context *context, + struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets, + struct wined3d_surface *depth_stencil_surface, DWORD color_location, + DWORD ds_location) +{ + struct wined3d_rendertarget_info depth_stencil = {{0}}; + unsigned int i; + + key->rb_namespace = 0; + if (depth_stencil_surface) + { + depth_stencil.resource = &depth_stencil_surface->container->resource; + depth_stencil.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil_surface); + depth_stencil.layer_count = 1; + } + context_set_fbo_key_for_render_target(context, key, 0, &depth_stencil, ds_location); + + for (i = 0; i < context->gl_info->limits.buffers; ++i) + context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location); } static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int object_count = gl_info->limits.buffers + 1; struct fbo_entry *entry; - entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); - entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets)); - memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = depth_stencil; - entry->color_location = color_location; - entry->ds_location = ds_location; + entry = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(struct fbo_entry, key.objects[object_count])); + memset(&entry->key, 0, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count])); + context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location); + entry->flags = 0; + if (depth_stencil) + { + if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH) + entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH; + if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL) + entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL; + } entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0); - entry->attached = FALSE; gl_info->fbo_ops.glGenFramebuffers(1, &entry->id); checkGLcall("glGenFramebuffers()"); TRACE("Created FBO %u.\n", entry->id); @@ -322,7 +514,7 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context * /* Context activation is done by the caller. */ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location, struct fbo_entry *entry) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -330,11 +522,15 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum targ context_bind_fbo(context, target, entry->id); context_clean_fbo_attachments(gl_info, target); - memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = depth_stencil; - entry->color_location = color_location; - entry->ds_location = ds_location; - entry->attached = FALSE; + context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location); + entry->flags = 0; + if (depth_stencil) + { + if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH) + entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH; + if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL) + entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL; + } } /* Context activation is done by the caller. */ @@ -347,39 +543,102 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb } --context->fbo_entry_count; list_remove(&entry->entry); - HeapFree(GetProcessHeap(), 0, entry->render_targets); HeapFree(GetProcessHeap(), 0, entry); } /* Context activation is done by the caller. */ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int object_count = gl_info->limits.buffers + 1; + struct wined3d_texture *rt_texture, *ds_texture; struct fbo_entry *entry; + unsigned int i, level; - if (depth_stencil && render_targets && render_targets[0]) + if (depth_stencil && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER) { - if (depth_stencil->resource.width < render_targets[0]->resource.width || - depth_stencil->resource.height < render_targets[0]->resource.height) + rt_texture = wined3d_texture_from_resource(render_targets[0].resource); + level = render_targets[0].sub_resource_idx % rt_texture->level_count; + ds_texture = depth_stencil->container; + + if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level) + < wined3d_texture_get_level_width(rt_texture, level) + || wined3d_texture_get_level_height(ds_texture, depth_stencil->texture_level) + < wined3d_texture_get_level_height(rt_texture, level)) { - WARN("Depth stencil is smaller than the primary color buffer, disabling\n"); + WARN("Depth stencil is smaller than the primary color buffer, disabling.\n"); depth_stencil = NULL; } + else if (ds_texture->resource.multisample_type != rt_texture->resource.multisample_type + || ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality) + { + WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n", + rt_texture->resource.multisample_type, rt_texture->resource.multisample_quality, + ds_texture->resource.multisample_type, ds_texture->resource.multisample_quality); + depth_stencil = NULL; + } + else + surface_set_compatible_renderbuffer(depth_stencil, &render_targets[0]); + } + + context_generate_fbo_key(context, context->fbo_key, render_targets, depth_stencil, color_location, + ds_location); + + if (TRACE_ON(d3d)) + { + TRACE("Dumping FBO attachments:\n"); + for (i = 0; i < gl_info->limits.buffers; ++i) + { + struct wined3d_resource *resource; + if ((resource = render_targets[i].resource)) + { + unsigned int width, height; + const char *resource_type; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + width = resource->size; + height = 1; + resource_type = "buffer"; + } + else + { + rt_texture = wined3d_texture_from_resource(resource); + level = render_targets[i].sub_resource_idx % rt_texture->level_count; + width = wined3d_texture_get_level_pow2_width(rt_texture, level); + height = wined3d_texture_get_level_pow2_height(rt_texture, level); + resource_type = "texture"; + } + + TRACE(" Color attachment %u: %p, %u format %s, %s %u, %ux%u, %u samples.\n", + i, resource, render_targets[i].sub_resource_idx, debug_d3dformat(resource->format->id), + context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : resource_type, + context->fbo_key->objects[i + 1].object, width, height, resource->multisample_type); + } + } + if (depth_stencil) + { + ds_texture = depth_stencil->container; + TRACE(" Depth attachment: %p format %s, %s %u, %ux%u, %u samples.\n", + depth_stencil, debug_d3dformat(ds_texture->resource.format->id), + context->fbo_key->rb_namespace & (1 << 0) ? "renderbuffer" : "texture", + context->fbo_key->objects[0].object, + wined3d_texture_get_level_pow2_width(ds_texture, depth_stencil->texture_level), + wined3d_texture_get_level_pow2_height(ds_texture, depth_stencil->texture_level), + ds_texture->resource.multisample_type); + } } LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry) { - if (!memcmp(entry->render_targets, - render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) - && entry->depth_stencil == depth_stencil && entry->color_location == color_location - && entry->ds_location == ds_location) - { - list_remove(&entry->entry); - list_add_head(&context->fbo_list, &entry->entry); - return entry; - } + if (memcmp(context->fbo_key, &entry->key, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count]))) + continue; + + list_remove(&entry->entry); + list_add_head(&context->fbo_list, &entry->entry); + return entry; } if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) @@ -405,9 +664,8 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; GLuint read_binding, draw_binding; - struct wined3d_surface *depth_stencil = entry->depth_stencil; - if (entry->attached) + if (entry->flags & WINED3D_FBO_ENTRY_FLAG_ATTACHED) { context_bind_fbo(context, target, entry->id); return; @@ -420,25 +678,12 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ /* Apply render targets */ for (i = 0; i < gl_info->limits.buffers; ++i) { - context_attach_surface_fbo(context, target, i, entry->render_targets[i], entry->color_location); + context_attach_surface_fbo(context, target, i, &entry->key.objects[i + 1], + entry->key.rb_namespace & (1 << (i + 1))); } - if (depth_stencil && entry->render_targets[0] - && (depth_stencil->resource.multisample_type - != entry->render_targets[0]->resource.multisample_type - || depth_stencil->resource.multisample_quality - != entry->render_targets[0]->resource.multisample_quality)) - { - WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n", - entry->render_targets[0]->resource.multisample_quality, - entry->render_targets[0]->resource.multisample_type, - depth_stencil->resource.multisample_quality, depth_stencil->resource.multisample_type); - depth_stencil = NULL; - } - - if (depth_stencil) - surface_set_compatible_renderbuffer(depth_stencil, entry->render_targets[0]); - context_attach_depth_stencil_fbo(context, target, depth_stencil, entry->ds_location); + context_attach_depth_stencil_fbo(context, target, &entry->key.objects[0], + entry->key.rb_namespace & 0x1, entry->flags); /* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility * GL contexts requirements. */ @@ -452,12 +697,12 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ context_bind_fbo(context, GL_READ_FRAMEBUFFER, read_binding); } - entry->attached = TRUE; + entry->flags |= WINED3D_FBO_ENTRY_FLAG_ATTACHED; } /* Context activation is done by the caller. */ static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { struct fbo_entry *entry, *entry2; @@ -490,11 +735,13 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) { - UINT clear_size = (context->gl_info->limits.buffers - 1) * sizeof(*context->blit_targets); - - context->blit_targets[0] = render_target; - if (clear_size) - memset(&context->blit_targets[1], 0, clear_size); + memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof(*context->blit_targets)); + if (render_target) + { + context->blit_targets[0].resource = &render_target->container->resource; + context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target); + context->blit_targets[0].layer_count = 1; + } context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location); } @@ -534,20 +781,12 @@ void context_free_occlusion_query(struct wined3d_occlusion_query *query) list_remove(&query->entry); query->context = NULL; - if (context->free_occlusion_query_count >= context->free_occlusion_query_size - 1) + if (!wined3d_array_reserve((void **)&context->free_occlusion_queries, + &context->free_occlusion_query_size, context->free_occlusion_query_count + 1, + sizeof(*context->free_occlusion_queries))) { - UINT new_size = context->free_occlusion_query_size << 1; - GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_occlusion_queries, - new_size * sizeof(*context->free_occlusion_queries)); - - if (!new_data) - { - ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); - return; - } - - context->free_occlusion_query_size = new_size; - context->free_occlusion_queries = new_data; + ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); + return; } context->free_occlusion_queries[context->free_occlusion_query_count++] = query->id; @@ -602,20 +841,12 @@ void context_free_event_query(struct wined3d_event_query *query) list_remove(&query->entry); query->context = NULL; - if (context->free_event_query_count >= context->free_event_query_size - 1) + if (!wined3d_array_reserve((void **)&context->free_event_queries, + &context->free_event_query_size, context->free_event_query_count + 1, + sizeof(*context->free_event_queries))) { - UINT new_size = context->free_event_query_size << 1; - union wined3d_gl_query_object *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries, - new_size * sizeof(*context->free_event_queries)); - - if (!new_data) - { - ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context); - return; - } - - context->free_event_query_size = new_size; - context->free_event_queries = new_data; + ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context); + return; } context->free_event_queries[context->free_event_query_count++] = query->object; @@ -649,29 +880,99 @@ void context_free_timestamp_query(struct wined3d_timestamp_query *query) list_remove(&query->entry); query->context = NULL; - if (context->free_timestamp_query_count >= context->free_timestamp_query_size - 1) + if (!wined3d_array_reserve((void **)&context->free_timestamp_queries, + &context->free_timestamp_query_size, context->free_timestamp_query_count + 1, + sizeof(*context->free_timestamp_queries))) { - UINT new_size = context->free_timestamp_query_size << 1; - GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_timestamp_queries, - new_size * sizeof(*context->free_timestamp_queries)); - - if (!new_data) - { - ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); - return; - } - - context->free_timestamp_query_size = new_size; - context->free_timestamp_queries = new_data; + ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context); + return; } context->free_timestamp_queries[context->free_timestamp_query_count++] = query->id; } +void context_alloc_so_statistics_query(struct wined3d_context *context, + struct wined3d_so_statistics_query *query) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (context->free_so_statistics_query_count) + { + query->u = context->free_so_statistics_queries[--context->free_so_statistics_query_count]; + } + else + { + GL_EXTCALL(glGenQueries(ARRAY_SIZE(query->u.id), query->u.id)); + checkGLcall("glGenQueries"); + + TRACE("Allocated SO statistics queries %u, %u in context %p.\n", + query->u.id[0], query->u.id[1], context); + } + + query->context = context; + list_add_head(&context->so_statistics_queries, &query->entry); +} + +void context_free_so_statistics_query(struct wined3d_so_statistics_query *query) +{ + struct wined3d_context *context = query->context; + + list_remove(&query->entry); + query->context = NULL; + + if (!wined3d_array_reserve((void **)&context->free_so_statistics_queries, + &context->free_so_statistics_query_size, context->free_so_statistics_query_count + 1, + sizeof(*context->free_so_statistics_queries))) + { + ERR("Failed to grow free list, leaking GL queries %u, %u in context %p.\n", + query->u.id[0], query->u.id[1], context); + return; + } + + context->free_so_statistics_queries[context->free_so_statistics_query_count++] = query->u; +} + +void context_alloc_pipeline_statistics_query(struct wined3d_context *context, + struct wined3d_pipeline_statistics_query *query) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (context->free_pipeline_statistics_query_count) + { + query->u = context->free_pipeline_statistics_queries[--context->free_pipeline_statistics_query_count]; + } + else + { + GL_EXTCALL(glGenQueries(ARRAY_SIZE(query->u.id), query->u.id)); + checkGLcall("glGenQueries"); + } + + query->context = context; + list_add_head(&context->pipeline_statistics_queries, &query->entry); +} + +void context_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) +{ + struct wined3d_context *context = query->context; + + list_remove(&query->entry); + query->context = NULL; + + if (!wined3d_array_reserve((void **)&context->free_pipeline_statistics_queries, + &context->free_pipeline_statistics_query_size, context->free_pipeline_statistics_query_count + 1, + sizeof(*context->free_pipeline_statistics_queries))) + { + ERR("Failed to grow free list, leaking GL queries in context %p.\n", context); + return; + } + + context->free_pipeline_statistics_queries[context->free_pipeline_statistics_query_count++] = query->u; +} + typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct fbo_entry *entry); -static void context_enum_surface_fbo_entries(const struct wined3d_device *device, - const struct wined3d_surface *surface, context_fbo_entry_func_t *callback) +static void context_enum_fbo_entries(const struct wined3d_device *device, + GLuint name, BOOL rb_namespace, context_fbo_entry_func_t *callback) { UINT i; @@ -681,21 +982,14 @@ static void context_enum_surface_fbo_entries(const struct wined3d_device *device const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry, *entry2; - if (context->current_rt == surface) context->current_rt = NULL; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) { UINT j; - if (entry->depth_stencil == surface) + for (j = 0; j < gl_info->limits.buffers + 1; ++j) { - callback(context, entry); - continue; - } - - for (j = 0; j < gl_info->limits.buffers; ++j) - { - if (entry->render_targets[j] == surface) + if (entry->key.objects[j].object == name + && !(entry->key.rb_namespace & (1 << j)) == !rb_namespace) { callback(context, entry); break; @@ -714,13 +1008,27 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context, void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource, enum wined3d_resource_type type) { - if (!device->d3d_initialized) return; + struct wined3d_texture *texture; + UINT i; + + if (!device->d3d_initialized) + return; switch (type) { - case WINED3D_RTYPE_SURFACE: - context_enum_surface_fbo_entries(device, surface_from_resource(resource), - context_queue_fbo_entry_destruction); + case WINED3D_RTYPE_TEXTURE_2D: + case WINED3D_RTYPE_TEXTURE_3D: + texture = texture_from_resource(resource); + + for (i = 0; i < device->context_count; ++i) + { + struct wined3d_context *context = device->contexts[i]; + if (context->current_rt.texture == texture) + { + context->current_rt.texture = NULL; + context->current_rt.sub_resource_idx = 0; + } + } break; default: @@ -728,24 +1036,10 @@ void context_resource_released(const struct wined3d_device *device, } } -static void context_detach_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +void context_gl_resource_released(struct wined3d_device *device, + GLuint name, BOOL rb_namespace) { - entry->attached = FALSE; -} - -void context_resource_unloaded(const struct wined3d_device *device, - struct wined3d_resource *resource, enum wined3d_resource_type type) -{ - switch (type) - { - case WINED3D_RTYPE_SURFACE: - context_enum_surface_fbo_entries(device, surface_from_resource(resource), - context_detach_fbo_entry); - break; - - default: - break; - } + context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction); } void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) @@ -756,28 +1050,59 @@ void context_surface_update(struct wined3d_context *context, const struct wined3 if (!entry || context->rebind_fbo) return; - for (i = 0; i < gl_info->limits.buffers; ++i) + for (i = 0; i < gl_info->limits.buffers + 1; ++i) { - if (surface == entry->render_targets[i]) + if (surface->container->texture_rgb.name == entry->key.objects[i].object + || surface->container->texture_srgb.name == entry->key.objects[i].object) { - TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i); + TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i); context->rebind_fbo = TRUE; return; } } - - if (surface == entry->depth_stencil) - { - TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface); - context->rebind_fbo = TRUE; - } } -static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format) +static BOOL context_restore_pixel_format(struct wined3d_context *ctx) { - int current = GetPixelFormat(dc); + const struct wined3d_gl_info *gl_info = ctx->gl_info; + BOOL ret = FALSE; - if (current == format) return TRUE; + if (ctx->restore_pf && IsWindow(ctx->restore_pf_win)) + { + if (ctx->gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) + { + HDC dc = GetDCEx(ctx->restore_pf_win, 0, DCX_USESTYLE | DCX_CACHE); + if (dc) + { + if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, ctx->restore_pf)))) + { + ERR("wglSetPixelFormatWINE failed to restore pixel format %d on window %p.\n", + ctx->restore_pf, ctx->restore_pf_win); + } + ReleaseDC(ctx->restore_pf_win, dc); + } + } + else + { + ERR("can't restore pixel format %d on window %p\n", ctx->restore_pf, ctx->restore_pf_win); + } + } + + ctx->restore_pf = 0; + ctx->restore_pf_win = NULL; + return ret; +} + +static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BOOL private, int format) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + int current; + + if (dc == context->hdc && context->hdc_is_private && context->hdc_has_format) + return TRUE; + + current = gl_info->gl_ops.wgl.p_wglGetPixelFormat(dc); + if (current == format) goto success; if (!current) { @@ -788,7 +1113,10 @@ static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC format, dc, GetLastError()); return FALSE; } - return TRUE; + + context->restore_pf = 0; + context->restore_pf_win = private ? NULL : WindowFromDC(dc); + goto success; } /* By default WGL doesn't allow pixel format adjustments but we need it @@ -797,13 +1125,25 @@ static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC * when really needed. */ if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) { + HWND win; + if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format))) { ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n", format, dc); return FALSE; } - return TRUE; + + win = private ? NULL : WindowFromDC(dc); + if (win != context->restore_pf_win) + { + context_restore_pixel_format(context); + + context->restore_pf = private ? 0 : current; + context->restore_pf_win = win; + } + + goto success; } /* OpenGL doesn't allow pixel format adjustments. Print an error and @@ -813,6 +1153,11 @@ static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n", format, dc, current); return TRUE; + +success: + if (dc == context->hdc && context->hdc_is_private) + context->hdc_has_format = TRUE; + return TRUE; } static BOOL context_set_gl_context(struct wined3d_context *ctx) @@ -820,7 +1165,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) struct wined3d_swapchain *swapchain = ctx->swapchain; BOOL backup = FALSE; - if (!context_set_pixel_format(ctx->gl_info, ctx->hdc, ctx->pixel_format)) + if (!context_set_pixel_format(ctx, ctx->hdc, ctx->hdc_is_private, ctx->pixel_format)) { WARN("Failed to set pixel format %d on device context %p.\n", ctx->pixel_format, ctx->hdc); @@ -840,7 +1185,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) * a swapchain, so we can't use the swapchain to get a backup dc. To * make this work windowless contexts would need to be handled by the * device. */ - if (ctx->destroyed) + if (ctx->destroyed || !swapchain) { FIXME("Unable to get backup dc for destroyed context %p.\n", ctx); context_set_current(NULL); @@ -853,7 +1198,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) return FALSE; } - if (!context_set_pixel_format(ctx->gl_info, dc, ctx->pixel_format)) + if (!context_set_pixel_format(ctx, dc, TRUE, ctx->pixel_format)) { ERR("Failed to set pixel format %d on device context %p.\n", ctx->pixel_format, dc); @@ -875,15 +1220,8 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) return TRUE; } -static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx, int pf) +static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx) { - if (!context_set_pixel_format(gl_info, dc, pf)) - { - ERR("Failed to restore pixel format %d on device context %p.\n", pf, dc); - context_set_current(NULL); - return; - } - if (!wglMakeCurrent(dc, gl_ctx)) { ERR("Failed to restore GL context %p on device context %p, last error %#x.\n", @@ -894,6 +1232,9 @@ static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HD static void context_update_window(struct wined3d_context *context) { + if (!context->swapchain) + return; + if (context->win_handle == context->swapchain->win_handle) return; @@ -904,6 +1245,8 @@ static void context_update_window(struct wined3d_context *context) wined3d_release_dc(context->win_handle, context->hdc); context->win_handle = context->swapchain->win_handle; + context->hdc_is_private = FALSE; + context->hdc_has_format = FALSE; context->needs_set = 1; context->valid = 1; @@ -917,6 +1260,8 @@ static void context_update_window(struct wined3d_context *context) static void context_destroy_gl_resources(struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_so_statistics_query *so_statistics_query; + struct wined3d_pipeline_statistics_query *pipeline_statistics_query; struct wined3d_timestamp_query *timestamp_query; struct wined3d_occlusion_query *occlusion_query; struct wined3d_event_query *event_query; @@ -924,17 +1269,31 @@ static void context_destroy_gl_resources(struct wined3d_context *context) HGLRC restore_ctx; HDC restore_dc; unsigned int i; - int restore_pf; restore_ctx = wglGetCurrentContext(); restore_dc = wglGetCurrentDC(); - restore_pf = GetPixelFormat(restore_dc); if (restore_ctx == context->glCtx) restore_ctx = NULL; else if (context->valid) context_set_gl_context(context); + LIST_FOR_EACH_ENTRY(so_statistics_query, &context->so_statistics_queries, + struct wined3d_so_statistics_query, entry) + { + if (context->valid) + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(so_statistics_query->u.id), so_statistics_query->u.id)); + so_statistics_query->context = NULL; + } + + LIST_FOR_EACH_ENTRY(pipeline_statistics_query, &context->pipeline_statistics_queries, + struct wined3d_pipeline_statistics_query, entry) + { + if (context->valid) + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(pipeline_statistics_query->u.id), pipeline_statistics_query->u.id)); + pipeline_statistics_query->context = NULL; + } + LIST_FOR_EACH_ENTRY(timestamp_query, &context->timestamp_queries, struct wined3d_timestamp_query, entry) { if (context->valid) @@ -982,6 +1341,24 @@ static void context_destroy_gl_resources(struct wined3d_context *context) GL_EXTCALL(glDeleteProgramsARB(1, &context->dummy_arbfp_prog)); } + if (gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY]) + { + for (i = 0; i < context->free_so_statistics_query_count; ++i) + { + union wined3d_gl_so_statistics_query *q = &context->free_so_statistics_queries[i]; + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); + } + } + + if (gl_info->supported[ARB_PIPELINE_STATISTICS_QUERY]) + { + for (i = 0; i < context->free_pipeline_statistics_query_count; ++i) + { + union wined3d_gl_pipeline_statistics_query *q = &context->free_pipeline_statistics_queries[i]; + GL_EXTCALL(glDeleteQueries(ARRAY_SIZE(q->id), q->id)); + } + } + if (gl_info->supported[ARB_TIMER_QUERY]) GL_EXTCALL(glDeleteQueries(context->free_timestamp_query_count, context->free_timestamp_queries)); @@ -1013,13 +1390,16 @@ static void context_destroy_gl_resources(struct wined3d_context *context) checkGLcall("context cleanup"); } + HeapFree(GetProcessHeap(), 0, context->free_so_statistics_queries); + HeapFree(GetProcessHeap(), 0, context->free_pipeline_statistics_queries); HeapFree(GetProcessHeap(), 0, context->free_timestamp_queries); HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries); HeapFree(GetProcessHeap(), 0, context->free_event_queries); + context_restore_pixel_format(context); if (restore_ctx) { - context_restore_gl_context(gl_info, restore_dc, restore_ctx, restore_pf); + context_restore_gl_context(gl_info, restore_dc, restore_ctx); } else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL)) { @@ -1073,8 +1453,9 @@ BOOL context_set_current(struct wined3d_context *ctx) { if (wglGetCurrentContext()) { + const struct wined3d_gl_info *gl_info = old->gl_info; TRACE("Flushing context %p before switching to %p.\n", old, ctx); - glFlush(); + gl_info->gl_ops.gl.p_glFlush(); } old->current = 0; } @@ -1093,7 +1474,7 @@ BOOL context_set_current(struct wined3d_context *ctx) return FALSE; ctx->current = 1; } - else if(wglGetCurrentContext()) + else if (wglGetCurrentContext()) { TRACE("Clearing current D3D context.\n"); if (!wglMakeCurrent(NULL, NULL)) @@ -1120,12 +1501,23 @@ void context_release(struct wined3d_context *context) WARN("Context %p is not the current context.\n", context); } - if (!--context->level && context->restore_ctx) + if (!--context->level) { - TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc); - context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx, context->restore_pf); - context->restore_ctx = NULL; - context->restore_dc = NULL; + if (context_restore_pixel_format(context)) + context->needs_set = 1; + if (context->restore_ctx) + { + TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc); + context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx); + context->restore_ctx = NULL; + context->restore_dc = NULL; + } + + if (context->destroy_delayed) + { + TRACE("Destroying context %p.\n", context); + context_destroy(context->device, context); + } } } @@ -1134,10 +1526,12 @@ void context_release(struct wined3d_context *context) * A to avoid breaking caller code. */ void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) { - if (context->current_rt != restore) + if (context->current_rt.texture != restore->container + || context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore)) { context_release(context); - context = context_acquire(restore->resource.device, restore); + context = context_acquire(restore->container->resource.device, + restore->container, surface_get_sub_resource_idx(restore)); } context_release(context); @@ -1158,12 +1552,24 @@ static void context_enter(struct wined3d_context *context) current_gl, wglGetCurrentDC()); context->restore_ctx = current_gl; context->restore_dc = wglGetCurrentDC(); - context->restore_pf = GetPixelFormat(context->restore_dc); context->needs_set = 1; } + else if (!context->needs_set && !(context->hdc_is_private && context->hdc_has_format) + && context->pixel_format != context->gl_info->gl_ops.wgl.p_wglGetPixelFormat(context->hdc)) + context->needs_set = 1; } } +void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) +{ + DWORD representative = context->state_table[state_id].representative - STATE_COMPUTE_OFFSET; + unsigned int index, shift; + + index = representative / (sizeof(*context->dirty_compute_states) * CHAR_BIT); + shift = representative & (sizeof(*context->dirty_compute_states) * CHAR_BIT - 1); + context->dirty_compute_states[index] |= (1u << shift); +} + void context_invalidate_state(struct wined3d_context *context, DWORD state) { DWORD rep = context->state_table[state].representative; @@ -1181,16 +1587,17 @@ void context_invalidate_state(struct wined3d_context *context, DWORD state) /* This function takes care of wined3d pixel format selection. */ static int context_choose_pixel_format(const struct wined3d_device *device, HDC hdc, const struct wined3d_format *color_format, const struct wined3d_format *ds_format, - BOOL auxBuffers, BOOL findCompatible) + BOOL auxBuffers) { - int iPixelFormat=0; - unsigned int current_value; unsigned int cfg_count = device->adapter->cfg_count; + unsigned int current_value; + PIXELFORMATDESCRIPTOR pfd; + int iPixelFormat = 0; unsigned int i; - TRACE("device %p, dc %p, color_format %s, ds_format %s, aux_buffers %#x, find_compatible %#x.\n", + TRACE("device %p, dc %p, color_format %s, ds_format %s, aux_buffers %#x.\n", device, hdc, debug_d3dformat(color_format->id), debug_d3dformat(ds_format->id), - auxBuffers, findCompatible); + auxBuffers); current_value = 0; for (i = 0; i < cfg_count; ++i) @@ -1245,16 +1652,11 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC } } - /* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */ - if(!iPixelFormat && !findCompatible) { - ERR("Can't find a suitable iPixelFormat\n"); - return FALSE; - } else if(!iPixelFormat) { - PIXELFORMATDESCRIPTOR pfd; + if (!iPixelFormat) + { + ERR("Trying to locate a compatible pixel format because an exact match failed.\n"); - TRACE("Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel format\n"); - /* PixelFormat selection */ - ZeroMemory(&pfd, sizeof(pfd)); + memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/ @@ -1266,53 +1668,77 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC pfd.cStencilBits = ds_format->stencil_size; pfd.iLayerType = PFD_MAIN_PLANE; - iPixelFormat = ChoosePixelFormat(hdc, &pfd); - if(!iPixelFormat) { - /* If this happens something is very wrong as ChoosePixelFormat barely fails */ - ERR("Can't find a suitable iPixelFormat\n"); - return FALSE; + if (!(iPixelFormat = ChoosePixelFormat(hdc, &pfd))) + { + /* Something is very wrong as ChoosePixelFormat() barely fails. */ + ERR("Can't find a suitable pixel format.\n"); + return 0; } } - TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s\n", + TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s.\n", iPixelFormat, debug_d3dformat(color_format->id), debug_d3dformat(ds_format->id)); return iPixelFormat; } /* Context activation is done by the caller. */ -static void bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) +void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i, count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); + unsigned int i; - for (i = 0; i < count; ++i) + for (i = 0; i < gl_info->limits.combined_samplers; ++i) { GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i)); checkGLcall("glActiveTexture"); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]); - checkGLcall("glBindTexture"); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, device->dummy_textures.tex_1d); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array); + + if (gl_info->supported[EXT_TEXTURE_ARRAY]) { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]); - checkGLcall("glBindTexture"); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, device->dummy_textures.tex_1d_array); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); } + + if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer); + + checkGLcall("Bind dummy textures"); } } +void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info, + const char *file, unsigned int line, const char *name) +{ + GLint err; + + if (gl_info->supported[ARB_DEBUG_OUTPUT] || (err = gl_info->gl_ops.gl.p_glGetError()) == GL_NO_ERROR) + { + TRACE("%s call ok %s / %u.\n", name, file, line); + return; + } + + do + { + ERR(">>>>>>> %s (%#x) from %s @ %s / %u.\n", + debug_glerror(err), err, name, file,line); + err = gl_info->gl_ops.gl.p_glGetError(); + } while (err != GL_NO_ERROR); +} + static BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info) { return gl_info->supported[ARB_DEBUG_OUTPUT] @@ -1379,58 +1805,63 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, } struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, - struct wined3d_surface *target, const struct wined3d_format *ds_format) + struct wined3d_texture *target, const struct wined3d_format *ds_format) { struct wined3d_device *device = swapchain->device; + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format *color_format; struct wined3d_context *ret; + BOOL hdc_is_private = FALSE; BOOL auxBuffers = FALSE; HGLRC ctx, share_ctx; + DWORD target_usage; int pixel_format; - unsigned int s; - int swap_interval; + unsigned int i; DWORD state; HDC hdc = 0; TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); + wined3d_from_cs(device->cs); + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); if (!ret) return NULL; - ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - gl_info->limits.buffers * sizeof(*ret->blit_targets)); - if (!ret->blit_targets) + if (!(ret->blit_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*ret->blit_targets)))) goto out; - ret->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - gl_info->limits.buffers * sizeof(*ret->draw_buffers)); - if (!ret->draw_buffers) + if (!(ret->draw_buffers = wined3d_calloc(gl_info->limits.buffers, sizeof(*ret->draw_buffers)))) + goto out; + + ret->fbo_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[gl_info->limits.buffers + 1])); + if (!ret->fbo_key) goto out; ret->free_timestamp_query_size = 4; - ret->free_timestamp_queries = HeapAlloc(GetProcessHeap(), 0, - ret->free_timestamp_query_size * sizeof(*ret->free_timestamp_queries)); - if (!ret->free_timestamp_queries) + if (!(ret->free_timestamp_queries = wined3d_calloc(ret->free_timestamp_query_size, + sizeof(*ret->free_timestamp_queries)))) goto out; list_init(&ret->timestamp_queries); ret->free_occlusion_query_size = 4; - ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0, - ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries)); - if (!ret->free_occlusion_queries) + if (!(ret->free_occlusion_queries = wined3d_calloc(ret->free_occlusion_query_size, + sizeof(*ret->free_occlusion_queries)))) goto out; - list_init(&ret->occlusion_queries); ret->free_event_query_size = 4; - ret->free_event_queries = HeapAlloc(GetProcessHeap(), 0, - ret->free_event_query_size * sizeof(*ret->free_event_queries)); - if (!ret->free_event_queries) + if (!(ret->free_event_queries = wined3d_calloc(ret->free_event_query_size, + sizeof(*ret->free_event_queries)))) goto out; - list_init(&ret->event_queries); + + list_init(&ret->so_statistics_queries); + + list_init(&ret->pipeline_statistics_queries); + list_init(&ret->fbo_list); list_init(&ret->fbo_destroy_list); @@ -1445,36 +1876,51 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, goto out; } -#if defined(STAGING_CSMT) - ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); - ret->current_fb.rt_size = gl_info->limits.buffers; - if (!ret->current_fb.render_targets) - goto out; - if (device->context_count) - ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; - -#endif /* STAGING_CSMT */ - /* Initialize the texture unit mapping to a 1:1 mapping */ - for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) + for (i = 0; i < ARRAY_SIZE(ret->tex_unit_map); ++i) + ret->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + for (i = 0; i < ARRAY_SIZE(ret->rev_tex_unit_map); ++i) + ret->rev_tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + if (gl_info->limits.graphics_samplers >= MAX_COMBINED_SAMPLERS) { - if (s < gl_info->limits.combined_samplers) + /* Initialize the texture unit mapping to a 1:1 mapping. */ + unsigned int base, count; + + wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_PIXEL, &base, &count); + if (base + MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(ret->rev_tex_unit_map)) { - ret->tex_unit_map[s] = s; - ret->rev_tex_unit_map[s] = s; + ERR("Unexpected texture unit base index %u.\n", base); + goto out; } - else + for (i = 0; i < min(count, MAX_FRAGMENT_SAMPLERS); ++i) { - ret->tex_unit_map[s] = WINED3D_UNMAPPED_STAGE; - ret->rev_tex_unit_map[s] = WINED3D_UNMAPPED_STAGE; + ret->tex_unit_map[i] = base + i; + ret->rev_tex_unit_map[base + i] = i; + } + + wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, &base, &count); + if (base + MAX_VERTEX_SAMPLERS > ARRAY_SIZE(ret->rev_tex_unit_map)) + { + ERR("Unexpected texture unit base index %u.\n", base); + goto out; + } + for (i = 0; i < min(count, MAX_VERTEX_SAMPLERS); ++i) + { + ret->tex_unit_map[MAX_FRAGMENT_SAMPLERS + i] = base + i; + ret->rev_tex_unit_map[base + i] = MAX_FRAGMENT_SAMPLERS + i; } } + if (!(ret->texture_type = wined3d_calloc(gl_info->limits.combined_samplers, + sizeof(*ret->texture_type)))) + goto out; + if (!(hdc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) { WARN("Failed to retrieve device context, trying swapchain backup.\n"); - if (!(hdc = swapchain_get_backup_dc(swapchain))) + if ((hdc = swapchain_get_backup_dc(swapchain))) + hdc_is_private = TRUE; + else { ERR("Failed to retrieve a device context.\n"); goto out; @@ -1482,6 +1928,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, } color_format = target->resource.format; + target_usage = target->resource.usage; /* In case of ORM_BACKBUFFER, make sure to request an alpha component for * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ @@ -1490,9 +1937,9 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, auxBuffers = TRUE; if (color_format->id == WINED3DFMT_B4G4R4X4_UNORM) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B4G4R4A4_UNORM); + color_format = wined3d_get_format(gl_info, WINED3DFMT_B4G4R4A4_UNORM, target_usage); else if (color_format->id == WINED3DFMT_B8G8R8X8_UNORM) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM); + color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); } /* DirectDraw supports 8bit paletted render targets and these are used by @@ -1502,9 +1949,9 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, * For this reason we require a format with 8bit alpha, so request * A8R8G8B8. */ if (color_format->id == WINED3DFMT_P8_UINT) - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM); + color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); - /* When "always_offscreen" is enabled, we only use the drawable for + /* When using FBOs for off-screen rendering, we only use the drawable for * presentation blits, and don't do any rendering to it. That means we * don't need depth or stencil buffers, and can mostly ignore the render * target format. This wouldn't necessarily be quite correct for 10bpc @@ -1512,33 +1959,21 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, * Using the same format regardless of the color/depth/stencil targets * makes it much less likely that different wined3d instances will set * conflicting pixel formats. */ - if (wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER - && wined3d_settings.always_offscreen) + if (wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) { - color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM); - ds_format = wined3d_get_format(gl_info, WINED3DFMT_UNKNOWN); + color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, target_usage); + ds_format = wined3d_get_format(gl_info, WINED3DFMT_UNKNOWN, WINED3DUSAGE_DEPTHSTENCIL); } /* Try to find a pixel format which matches our requirements. */ - pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers, FALSE); - - /* Try to locate a compatible format if we weren't able to find anything. */ - if (!pixel_format) - { - TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); - pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers, TRUE); - } - - /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */ - if (!pixel_format) - { - ERR("Can't find a suitable pixel format.\n"); + if (!(pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers))) goto out; - } + + ret->gl_info = gl_info; context_enter(ret); - if (!context_set_pixel_format(gl_info, hdc, pixel_format)) + if (!context_set_pixel_format(ret, hdc, hdc_is_private, pixel_format)) { ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc); context_release(ret); @@ -1579,29 +2014,32 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, goto out; } - ret->gl_info = gl_info; - ret->d3d_info = &device->adapter->d3d_info; + ret->d3d_info = d3d_info; ret->state_table = device->StateTable; - /* Mark all states dirty to force a proper initialization of the states - * on the first use of the context. */ + /* Mark all states dirty to force a proper initialization of the states on + * the first use of the context. Compute states do not need initialization. */ for (state = 0; state <= STATE_HIGHEST; ++state) { - if (ret->state_table[state].representative) + if (ret->state_table[state].representative && !STATE_IS_COMPUTE(state)) context_invalidate_state(ret, state); } + ret->device = device; ret->swapchain = swapchain; - ret->current_rt = target; + ret->current_rt.texture = target; + ret->current_rt.sub_resource_idx = 0; ret->tid = GetCurrentThreadId(); - ret->render_offscreen = wined3d_resource_is_offscreen(&target->container->resource); + ret->render_offscreen = wined3d_resource_is_offscreen(&target->resource); ret->draw_buffers_mask = context_generate_rt_mask(GL_BACK); ret->valid = 1; ret->glCtx = ctx; ret->win_handle = swapchain->win_handle; ret->hdc = hdc; + ret->hdc_is_private = hdc_is_private; + ret->hdc_has_format = TRUE; ret->pixel_format = pixel_format; ret->needs_set = 1; @@ -1643,55 +2081,23 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, } } - switch (swapchain->desc.swap_interval) - { - case WINED3DPRESENT_INTERVAL_IMMEDIATE: - swap_interval = 0; - break; - case WINED3DPRESENT_INTERVAL_DEFAULT: - case WINED3DPRESENT_INTERVAL_ONE: - swap_interval = 1; - break; - case WINED3DPRESENT_INTERVAL_TWO: - swap_interval = 2; - break; - case WINED3DPRESENT_INTERVAL_THREE: - swap_interval = 3; - break; - case WINED3DPRESENT_INTERVAL_FOUR: - swap_interval = 4; - break; - default: - FIXME("Unknown swap interval %#x.\n", swapchain->desc.swap_interval); - swap_interval = 1; - } - - if (gl_info->supported[WGL_EXT_SWAP_CONTROL]) - { - if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval))) - ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n", - swap_interval, ret, GetLastError()); - } - - gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers); + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers); TRACE("Setting up the screen\n"); - gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);"); + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);"); - gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); - checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);"); + gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);"); - gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); - checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); - - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment); - checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);"); - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);"); - - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); + checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); + } + else { GLuint vao; @@ -1700,6 +2106,11 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, checkGLcall("creating VAO"); } + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment); + checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);"); + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, 1);"); + if (gl_info->supported[ARB_VERTEX_BLEND]) { /* Direct3D always uses n-1 weights for n world matrices and uses @@ -1714,11 +2125,11 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d * the previous texture where to source the offset from is always unit - 1. */ - for (s = 1; s < gl_info->limits.textures; ++s) + for (i = 1; i < gl_info->limits.textures; ++i) { - context_active_texture(ret, gl_info, s); + context_active_texture(ret, gl_info, i); gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, - GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1); + GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + i - 1); checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ..."); } } @@ -1744,9 +2155,9 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, if (gl_info->supported[ARB_POINT_SPRITE]) { - for (s = 0; s < gl_info->limits.textures; ++s) + for (i = 0; i < gl_info->limits.textures; ++i) { - context_active_texture(ret, gl_info, s); + context_active_texture(ret, gl_info, i); gl_info->gl_ops.gl.p_glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)"); } @@ -1760,16 +2171,39 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, { GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT)); } + if (!(d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART)) + { + if (gl_info->supported[ARB_ES3_COMPATIBILITY]) + { + gl_info->gl_ops.gl.p_glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + checkGLcall("enable GL_PRIMITIVE_RESTART_FIXED_INDEX"); + } + else + { + FIXME("OpenGL implementation does not support GL_PRIMITIVE_RESTART_FIXED_INDEX.\n"); + } + } + if (!(d3d_info->wined3d_creation_flags & WINED3D_LEGACY_CUBEMAP_FILTERING) + && gl_info->supported[ARB_SEAMLESS_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + checkGLcall("enable seamless cube map filtering"); + } + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT)); device->shader_backend->shader_init_context_state(ret); ret->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) - | (1u << WINED3D_SHADER_TYPE_GEOMETRY); + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN) + | (1u << WINED3D_SHADER_TYPE_COMPUTE); /* If this happens to be the first context for the device, dummy textures * are not created yet. In that case, they will be created (and bound) by * create_dummy_textures right after this context is initialized. */ - if (device->dummy_texture_2d[0]) - bind_dummy_textures(device, ret); + if (device->dummy_textures.tex_2d) + context_bind_dummy_textures(device, ret); TRACE("Created context %p.\n", ret); @@ -1779,12 +2213,11 @@ out: if (hdc) wined3d_release_dc(swapchain->win_handle, hdc); device->shader_backend->shader_free_context_data(ret); device->adapter->fragment_pipe->free_context_data(ret); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, ret->current_fb.render_targets); -#endif /* STAGING_CSMT */ + HeapFree(GetProcessHeap(), 0, ret->texture_type); HeapFree(GetProcessHeap(), 0, ret->free_event_queries); HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); + HeapFree(GetProcessHeap(), 0, ret->fbo_key); HeapFree(GetProcessHeap(), 0, ret->draw_buffers); HeapFree(GetProcessHeap(), 0, ret->blit_targets); HeapFree(GetProcessHeap(), 0, ret); @@ -1797,6 +2230,19 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont TRACE("Destroying ctx %p\n", context); + wined3d_from_cs(device->cs); + + /* We delay destroying a context when it is active. The context_release() + * function invokes context_destroy() again while leaving the last level. */ + if (context->level) + { + TRACE("Delaying destruction of context %p.\n", context); + context->destroy_delayed = 1; + /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */ + context->swapchain = NULL; + return; + } + if (context->tid == GetCurrentThreadId() || !context->current) { context_destroy_gl_resources(context); @@ -1816,15 +2262,51 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont device->shader_backend->shader_free_context_data(context); device->adapter->fragment_pipe->free_context_data(context); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, context->current_fb.render_targets); -#endif /* STAGING_CSMT */ + HeapFree(GetProcessHeap(), 0, context->texture_type); + HeapFree(GetProcessHeap(), 0, context->fbo_key); HeapFree(GetProcessHeap(), 0, context->draw_buffers); HeapFree(GetProcessHeap(), 0, context->blit_targets); device_context_remove(device, context); if (destroy) HeapFree(GetProcessHeap(), 0, context); } +const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, + const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (!shader_version) + { + *base = 0; + *count = MAX_TEXTURES; + return context->tex_unit_map; + } + + if (shader_version->major >= 4) + { + wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, shader_version->type, base, count); + return NULL; + } + + switch (shader_version->type) + { + case WINED3D_SHADER_TYPE_PIXEL: + *base = 0; + *count = MAX_FRAGMENT_SAMPLERS; + break; + case WINED3D_SHADER_TYPE_VERTEX: + *base = MAX_FRAGMENT_SAMPLERS; + *count = MAX_VERTEX_SAMPLERS; + break; + default: + ERR("Unhandled shader type %#x.\n", shader_version->type); + *base = 0; + *count = 0; + } + + return context->tex_unit_map; +} + /* Context activation is done by the caller. */ static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height) { @@ -1846,9 +2328,10 @@ static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width static void context_get_rt_size(const struct wined3d_context *context, SIZE *size) { - const struct wined3d_surface *rt = context->current_rt; + const struct wined3d_texture *rt = context->current_rt.texture; + unsigned int level; - if (rt->container->swapchain && rt->container->swapchain->front_buffer == rt->container) + if (rt->swapchain) { RECT window_size; @@ -1859,8 +2342,9 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz return; } - size->cx = rt->resource.width; - size->cy = rt->resource.height; + level = context->current_rt.sub_resource_idx % rt->level_count; + size->cx = wined3d_texture_get_level_width(rt, level); + size->cy = wined3d_texture_get_level_height(rt, level); } /***************************************************************************** @@ -2049,6 +2533,10 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); + /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); + set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); /* Disable shaders */ @@ -2144,6 +2632,16 @@ void context_active_texture(struct wined3d_context *context, const struct wined3 context->active_texture = unit; } +void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (binding == GL_ELEMENT_ARRAY_BUFFER) + context_invalidate_state(context, STATE_INDEXBUFFER); + + GL_EXTCALL(glBindBuffer(binding, name)); +} + void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -2162,46 +2660,115 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint if (old_texture_type != target) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; switch (old_texture_type) { case GL_NONE: /* nothing to do */ break; + case GL_TEXTURE_1D: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, device->dummy_textures.tex_1d); + checkGLcall("glBindTexture"); + break; + case GL_TEXTURE_1D_ARRAY: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, device->dummy_textures.tex_1d_array); + checkGLcall("glBindTexture"); + break; case GL_TEXTURE_2D: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); + checkGLcall("glBindTexture"); + break; + case GL_TEXTURE_2D_ARRAY: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); checkGLcall("glBindTexture"); break; case GL_TEXTURE_RECTANGLE_ARB: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); checkGLcall("glBindTexture"); break; case GL_TEXTURE_CUBE_MAP: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); + checkGLcall("glBindTexture"); + break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array); checkGLcall("glBindTexture"); break; case GL_TEXTURE_3D: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); + checkGLcall("glBindTexture"); + break; + case GL_TEXTURE_BUFFER: + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer); checkGLcall("glBindTexture"); break; default: - ERR("Unexpected texture target %#x\n", old_texture_type); + ERR("Unexpected texture target %#x.\n", old_texture_type); } context->texture_type[unit] = target; } } +void *context_map_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, size_t size, GLenum binding, DWORD flags) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + BYTE *memory; + + if (!data->buffer_object) + return data->addr; + + context_bind_bo(context, binding, data->buffer_object); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield map_flags = wined3d_resource_gl_map_flags(flags) & ~GL_MAP_FLUSH_EXPLICIT_BIT; + memory = GL_EXTCALL(glMapBufferRange(binding, (INT_PTR)data->addr, size, map_flags)); + } + else + { + memory = GL_EXTCALL(glMapBuffer(binding, wined3d_resource_gl_legacy_map_flags(flags))); + memory += (INT_PTR)data->addr; + } + + context_bind_bo(context, binding, 0); + checkGLcall("Map buffer object"); + + return memory; +} + +void context_unmap_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, GLenum binding) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (!data->buffer_object) + return; + + context_bind_bo(context, binding, data->buffer_object); + GL_EXTCALL(glUnmapBuffer(binding)); + context_bind_bo(context, binding, 0); + checkGLcall("Unmap buffer object"); +} + static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen) { - if (context->render_offscreen == offscreen) return; + if (context->render_offscreen == offscreen) + return; - context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); context_invalidate_state(context, STATE_VIEWPORT); context_invalidate_state(context, STATE_SCISSORRECT); - context_invalidate_state(context, STATE_FRONTFACE); + if (!context->gl_info->supported[ARB_CLIP_CONTROL]) + { + context_invalidate_state(context, STATE_FRONTFACE); + context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); + } + context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN)); + if (context->gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); context->render_offscreen = offscreen; } @@ -2227,7 +2794,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, const struct wined3d_rendertarget_view *depth_stencil) { /* Onscreen surfaces are always in a swapchain */ - struct wined3d_swapchain *swapchain = context->current_rt->container->swapchain; + struct wined3d_swapchain *swapchain = context->current_rt.texture->swapchain; if (context->render_offscreen || !depth_stencil) return; if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->format)) return; @@ -2238,43 +2805,45 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&context->current_rt->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + if (!(wined3d_texture_load_location(context->current_rt.texture, context->current_rt.sub_resource_idx, + context, WINED3D_LOCATION_TEXTURE_RGB))) + ERR("Failed to load location.\n"); swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); context_set_render_offscreen(context, TRUE); } -static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, const struct wined3d_surface *rt) +GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) { - if (!rt || rt->resource.format->id == WINED3DFMT_NULL) - return 0; - else if (rt->container->swapchain) - return context_generate_rt_mask_from_surface(rt); - else - return context_generate_rt_mask(context->offscreenBuffer); -#else /* STAGING_CSMT */ - surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB); - swapchain->render_to_fbo = TRUE; - swapchain_update_draw_bindings(swapchain); - context_set_render_offscreen(context, TRUE); + switch (wined3d_settings.offscreen_rendering_mode) + { + case ORM_FBO: + return GL_COLOR_ATTACHMENT0; + + case ORM_BACKBUFFER: + return context->aux_buffers > 0 ? GL_AUX0 : GL_BACK; + + default: + FIXME("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode); + return GL_BACK; + } } -static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt) +static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_texture *rt) { if (!rt || rt->resource.format->id == WINED3DFMT_NULL) return 0; - else if (rt->container->swapchain) - return context_generate_rt_mask_from_surface(rt); + else if (rt->swapchain) + return context_generate_rt_mask_from_resource(&rt->resource); else - return context_generate_rt_mask(device->offscreenBuffer); -#endif /* STAGING_CSMT */ + return context_generate_rt_mask(context_get_offscreen_gl_buffer(context)); } /* Context activation is done by the caller. */ void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) { - struct wined3d_surface *rt = context->current_rt; + struct wined3d_texture *rt = context->current_rt.texture; + struct wined3d_surface *surface; DWORD rt_mask, *cur_mask; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) @@ -2283,9 +2852,10 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine if (context->render_offscreen) { - wined3d_texture_load(rt->container, context, FALSE); + wined3d_texture_load(rt, context, FALSE); - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, rt, NULL, rt->container->resource.draw_binding); + surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface; + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL) rt_mask = 1; else @@ -2295,16 +2865,12 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine { context->current_fbo = NULL; context_bind_fbo(context, GL_FRAMEBUFFER, 0); - rt_mask = context_generate_rt_mask_from_surface(rt); + rt_mask = context_generate_rt_mask_from_resource(&rt->resource); } } else { -#if defined(STAGING_CSMT) rt_mask = context_generate_rt_mask_no_fbo(context, rt); -#else /* STAGING_CSMT */ - rt_mask = context_generate_rt_mask_no_fbo(device, rt); -#endif /* STAGING_CSMT */ } cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; @@ -2342,21 +2908,17 @@ static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarge } /* Context activation is done by the caller. */ -BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, +BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state, UINT rt_count, const struct wined3d_fb_state *fb) { struct wined3d_rendertarget_view **rts = fb->render_targets; struct wined3d_rendertarget_view *dsv = fb->depth_stencil; const struct wined3d_gl_info *gl_info = context->gl_info; DWORD rt_mask = 0, *cur_mask; - UINT i; + unsigned int i; -#if defined(STAGING_CSMT) - if (isStateDirty(context, STATE_FRAMEBUFFER) || !wined3d_fb_equal(fb, &context->current_fb) -#else /* STAGING_CSMT */ - if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb -#endif /* STAGING_CSMT */ - || rt_count != context->gl_info->limits.buffers) + if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb + || rt_count != gl_info->limits.buffers) { if (!context_validate_rt_config(rt_count, rts, dsv)) return FALSE; @@ -2367,17 +2929,19 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource)) { + memset(context->blit_targets, 0, gl_info->limits.buffers * sizeof(*context->blit_targets)); for (i = 0; i < rt_count; ++i) { - context->blit_targets[i] = wined3d_rendertarget_view_get_surface(rts[i]); + if (rts[i]) + { + context->blit_targets[i].gl_view = rts[i]->gl_view; + context->blit_targets[i].resource = rts[i]->resource; + context->blit_targets[i].sub_resource_idx = rts[i]->sub_resource_idx; + context->blit_targets[i].layer_count = rts[i]->layer_count; + } if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL) rt_mask |= (1u << i); } - while (i < context->gl_info->limits.buffers) - { - context->blit_targets[i] = NULL; - ++i; - } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, wined3d_rendertarget_view_get_surface(dsv), rt_count ? rts[0]->resource->draw_binding : 0, @@ -2387,7 +2951,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win { context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE); - rt_mask = context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); + rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource); } /* If the framebuffer is not the device's fb the device's fb has to be reapplied @@ -2397,17 +2961,9 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } else { -#if defined(STAGING_CSMT) rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); } - - wined3d_fb_copy(&context->current_fb, fb); -#else /* STAGING_CSMT */ - rt_mask = context_generate_rt_mask_no_fbo(device, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } -#endif /* STAGING_CSMT */ } else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) @@ -2420,12 +2976,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win } else { -#if defined(STAGING_CSMT) rt_mask = context_generate_rt_mask_no_fbo(context, -#else /* STAGING_CSMT */ - rt_mask = context_generate_rt_mask_no_fbo(device, -#endif /* STAGING_CSMT */ - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL); } cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; @@ -2442,18 +2994,16 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win context_check_fbo_status(context, GL_FRAMEBUFFER); } - if (context->last_was_blit) - context->last_was_blit = FALSE; + context->last_was_blit = FALSE; /* Blending and clearing should be orthogonal, but tests on the nvidia * driver show that disabling blending when clearing improves the clearing * performance incredibly. */ gl_info->gl_ops.gl.p_glDisable(GL_BLEND); gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST); - if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) + if (rt_count && gl_info->supported[ARB_FRAMEBUFFER_SRGB]) { - if (!(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) - || device->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) + if (needs_srgb_write(context, state, fb)) gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); else gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); @@ -2468,30 +3018,17 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win return TRUE; } -#if defined(STAGING_CSMT) static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) { - struct wined3d_rendertarget_view **rts = state->fb.render_targets; - struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - DWORD rt_mask, rt_mask_bits; - unsigned int i; - - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); -#else /* STAGING_CSMT */ -static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) -{ - const struct wined3d_state *state = &device->state; struct wined3d_rendertarget_view **rts = state->fb->render_targets; struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; DWORD rt_mask, rt_mask_bits; unsigned int i; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0])); -#endif /* STAGING_CSMT */ + return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])->container); else if (!context->render_offscreen) - return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); + return context_generate_rt_mask_from_resource(rts[0]->resource); rt_mask = ps ? ps->reg_maps.rt_mask : 1; rt_mask &= context->d3d_info->valid_rt_mask; @@ -2512,14 +3049,8 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const /* Context activation is done by the caller. */ void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) - const struct wined3d_fb_state *fb = &state->fb; DWORD rt_mask = find_draw_buffers_mask(context, state); -#else /* STAGING_CSMT */ - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_fb_state *fb = state->fb; - DWORD rt_mask = find_draw_buffers_mask(context, device); -#endif /* STAGING_CSMT */ DWORD *cur_mask; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) @@ -2533,13 +3064,20 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat { unsigned int i; + memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof (*context->blit_targets)); for (i = 0; i < context->gl_info->limits.buffers; ++i) { - context->blit_targets[i] = wined3d_rendertarget_view_get_surface(fb->render_targets[i]); + if (fb->render_targets[i]) + { + context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view; + context->blit_targets[i].resource = fb->render_targets[i]->resource; + context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx; + context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count; + } } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, wined3d_rendertarget_view_get_surface(fb->depth_stencil), - fb->render_targets[0]->resource->draw_binding, + fb->render_targets[0] ? fb->render_targets[0]->resource->draw_binding : 0, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0); } } @@ -2550,10 +3088,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat context_apply_draw_buffers(context, rt_mask); *cur_mask = rt_mask; } -#if defined(STAGING_CSMT) - - wined3d_fb_copy(&context->current_fb, &state->fb); -#endif /* STAGING_CSMT */ + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; } static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) @@ -2637,15 +3172,9 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i, tex; WORD ffu_map; - context_update_fixed_function_usage_map(context, state); - - if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS) - return; - ffu_map = context->fixed_function_usage_map; if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages @@ -2687,14 +3216,10 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context, static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state) { const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_shader_resource_info *resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info; unsigned int i; - if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS) - return; - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) { if (resource_info[i].type && context->tex_unit_map[i] != i) @@ -2739,12 +3264,9 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info; const struct wined3d_shader_resource_info *ps_resource_info = NULL; const struct wined3d_gl_info *gl_info = context->gl_info; - int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1; + int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.graphics_samplers) - 1; int i; - if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS) - return; - /* Note that we only care if a resource is used or not, not the * resource's specific type. Otherwise we'd need to call * shader_update_samplers() here for 1.x pixelshaders. */ @@ -2780,14 +3302,21 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons static void context_update_tex_unit_map(struct wined3d_context *context, const struct wined3d_state *state) { + const struct wined3d_gl_info *gl_info = context->gl_info; BOOL vs = use_vs(state); BOOL ps = use_ps(state); + if (!ps) + context_update_fixed_function_usage_map(context, state); + /* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders * need a 1:1 map at the moment. * When the mapping of a stage is changed, sampler and ALL texture stage * states have to be reset. */ + if (gl_info->limits.graphics_samplers >= MAX_COMBINED_SAMPLERS) + return; + if (ps) context_map_psamplers(context, state); else @@ -2800,22 +3329,12 @@ static void context_update_tex_unit_map(struct wined3d_context *context, const s /* Context activation is done by the caller. */ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) DWORD rt_mask, *cur_mask; if (isStateDirty(context, STATE_FRAMEBUFFER)) return; cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; rt_mask = find_draw_buffers_mask(context, state); -#else /* STAGING_CSMT */ - const struct wined3d_device *device = context->swapchain->device; - DWORD rt_mask, *cur_mask; - - if (isStateDirty(context, STATE_FRAMEBUFFER)) return; - - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; - rt_mask = find_draw_buffers_mask(context, device); -#endif /* STAGING_CSMT */ if (rt_mask != *cur_mask) { context_apply_draw_buffers(context, rt_mask); @@ -2843,8 +3362,8 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) *regnum = WINED3D_FFP_TEXCOORD0 + usage_idx; else { - FIXME("Unsupported input stream [usage=%s, usage_idx=%u].\n", debug_d3ddeclusage(usage), usage_idx); - *regnum = ~0U; + WARN("Unsupported input stream [usage=%s, usage_idx=%u].\n", debug_d3ddeclusage(usage), usage_idx); + *regnum = ~0u; return FALSE; } @@ -2852,17 +3371,23 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) } /* Context activation is done by the caller. */ -void context_stream_info_from_declaration(struct wined3d_context *context, - const struct wined3d_state *state, struct wined3d_stream_info *stream_info) +void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, + const struct wined3d_state *state, const struct wined3d_gl_info *gl_info, + const struct wined3d_d3d_info *d3d_info) { /* We need to deal with frequency data! */ struct wined3d_vertex_declaration *declaration = state->vertex_declaration; + BOOL generic_attributes = d3d_info->ffp_generic_attributes; BOOL use_vshader = use_vs(state); - BOOL generic_attributes = context->d3d_info->ffp_generic_attributes; unsigned int i; stream_info->use_map = 0; stream_info->swizzle_map = 0; + stream_info->position_transformed = 0; + + if (!declaration) + return; + stream_info->position_transformed = declaration->position_transformed; /* Translate the declaration into strided data. */ @@ -2944,7 +3469,7 @@ void context_stream_info_from_declaration(struct wined3d_context *context, stream_info->elements[idx].divisor = 0; } - if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA] + if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && element->format->id == WINED3DFMT_B8G8R8A8_UNORM) { stream_info->swizzle_map |= 1u << idx; @@ -2957,14 +3482,14 @@ void context_stream_info_from_declaration(struct wined3d_context *context, /* Context activation is done by the caller. */ static void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; struct wined3d_stream_info *stream_info = &context->stream_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_gl_info *gl_info = context->gl_info; DWORD prev_all_vbo = stream_info->all_vbo; unsigned int i; WORD map; - context_stream_info_from_declaration(context, state, stream_info); + wined3d_stream_info_from_declaration(stream_info, state, gl_info, d3d_info); stream_info->all_vbo = 1; context->num_buffer_queries = 0; @@ -2986,20 +3511,21 @@ static void context_update_stream_info(struct wined3d_context *context, const st * sources. In most sane cases the pointer - offset will still be > 0, * otherwise it will wrap around to some big value. Hope that with the * indices the driver wraps it back internally. If not, - * drawStridedSlow is needed, including a vertex buffer path. */ + * draw_primitive_immediate_mode() is needed, including a vertex buffer + * path. */ if (state->load_base_vertex_index < 0) { WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index); element->data.buffer_object = 0; - element->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context); + element->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(buffer, context); if ((UINT_PTR)element->data.addr < -state->load_base_vertex_index * element->stride) FIXME("System memory vertex data load offset is negative!\n"); } else { - buffer_internal_preload(buffer, context, state); - buffer_get_memory(buffer, context, &data); + wined3d_buffer_load(buffer, context, state); + wined3d_buffer_get_memory(buffer, &data, buffer->locations); element->data.buffer_object = data.buffer_object; element->data.addr += (ULONG_PTR)data.addr; } @@ -3013,37 +3539,32 @@ static void context_update_stream_info(struct wined3d_context *context, const st TRACE("Load array %u {%#x:%p}.\n", i, element->data.buffer_object, element->data.addr); } + if (prev_all_vbo != stream_info->all_vbo) + context_invalidate_state(context, STATE_INDEXBUFFER); + + context->use_immediate_mode_draw = FALSE; + + if (stream_info->all_vbo) + return; + if (use_vs(state)) { - if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) + if (state->vertex_declaration->half_float_conv_needed) { -#if defined(STAGING_CSMT) - TRACE("Using draw_strided_slow with vertex shaders for FLOAT16 conversion.\n"); -#else /* STAGING_CSMT */ - TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); -#endif /* STAGING_CSMT */ + TRACE("Using immediate mode draw with vertex shaders for FLOAT16 conversion.\n"); context->use_immediate_mode_draw = TRUE; } - else - { - context->use_immediate_mode_draw = FALSE; - } } else { WORD slow_mask = -!d3d_info->ffp_generic_attributes & (1u << WINED3D_FFP_PSIZE); - slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] - & ((1u << WINED3D_FFP_DIFFUSE) | (1u << WINED3D_FFP_SPECULAR)); + slow_mask |= -(!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && !d3d_info->ffp_generic_attributes) + & ((1u << WINED3D_FFP_DIFFUSE) | (1u << WINED3D_FFP_SPECULAR) | (1u << WINED3D_FFP_BLENDWEIGHT)); - if (((stream_info->position_transformed && !d3d_info->xyzrhw) - || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo) + if ((stream_info->position_transformed && !d3d_info->xyzrhw) + || (stream_info->use_map & slow_mask)) context->use_immediate_mode_draw = TRUE; - else - context->use_immediate_mode_draw = FALSE; } - - if (prev_all_vbo != stream_info->all_vbo) - context_invalidate_state(context, STATE_INDEXBUFFER); } /* Context activation is done by the caller. */ @@ -3092,7 +3613,8 @@ static void context_preload_textures(struct wined3d_context *context, const stru } } -static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state) +static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state, + unsigned int shader_mask) { struct wined3d_shader_sampler_map_entry *entry; struct wined3d_shader_resource_view *view; @@ -3101,13 +3623,16 @@ static void context_load_shader_resources(struct wined3d_context *context, const for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { + if (!(shader_mask & (1u << i))) + continue; + if (!(shader = state->shader[i])) continue; for (j = 0; j < WINED3D_MAX_CBS; ++j) { if (state->cb[i][j]) - buffer_internal_preload(state->cb[i][j], context, state); + wined3d_buffer_load(state->cb[i][j], context, state); } for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) @@ -3115,115 +3640,171 @@ static void context_load_shader_resources(struct wined3d_context *context, const entry = &shader->reg_maps.sampler_map.entries[j]; if (!(view = state->shader_resource_view[i][entry->resource_idx])) - { - WARN("No resource view bound at index %u, %u.\n", i, entry->resource_idx); continue; - } if (view->resource->type == WINED3D_RTYPE_BUFFER) - buffer_internal_preload(buffer_from_resource(view->resource), context, state); + wined3d_buffer_load(buffer_from_resource(view->resource), context, state); else - wined3d_texture_load(wined3d_texture_from_resource(view->resource), context, FALSE); + wined3d_texture_load(texture_from_resource(view->resource), context, FALSE); } } } -static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state) +static void context_bind_shader_resources(struct wined3d_context *context, + const struct wined3d_state *state, enum wined3d_shader_type shader_type) { - const struct wined3d_device *device = context->swapchain->device; - const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int bind_idx, shader_sampler_count, base, count, i; + const struct wined3d_device *device = context->device; struct wined3d_shader_sampler_map_entry *entry; struct wined3d_shader_resource_view *view; + const struct wined3d_shader *shader; struct wined3d_sampler *sampler; - struct wined3d_texture *texture; - struct wined3d_shader *shader; - unsigned int i, j, count; - GLuint sampler_name; + const DWORD *tex_unit_map; - static const struct + if (!(shader = state->shader[shader_type])) + return; + + tex_unit_map = context_get_tex_unit_mapping(context, + &shader->reg_maps.shader_version, &base, &count); + + shader_sampler_count = shader->reg_maps.sampler_map.count; + if (shader_sampler_count > count) + FIXME("Shader %p needs %u samplers, but only %u are supported.\n", + shader, shader_sampler_count, count); + count = min(shader_sampler_count, count); + + for (i = 0; i < count; ++i) { - enum wined3d_shader_type type; - unsigned int base_idx; - unsigned int count; + entry = &shader->reg_maps.sampler_map.entries[i]; + bind_idx = base + entry->bind_idx; + if (tex_unit_map) + bind_idx = tex_unit_map[bind_idx]; + + if (!(view = state->shader_resource_view[shader_type][entry->resource_idx])) + { + WARN("No resource view bound at index %u, %u.\n", shader_type, entry->resource_idx); + continue; + } + + if (entry->sampler_idx == WINED3D_SAMPLER_DEFAULT) + sampler = device->default_sampler; + else if (!(sampler = state->sampler[shader_type][entry->sampler_idx])) + sampler = device->null_sampler; + wined3d_shader_resource_view_bind(view, bind_idx, sampler, context); } - shader_types[] = - { - {WINED3D_SHADER_TYPE_PIXEL, 0, MAX_FRAGMENT_SAMPLERS}, - {WINED3D_SHADER_TYPE_VERTEX, MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS}, - }; +} - for (i = 0; i < ARRAY_SIZE(shader_types); ++i) +static void context_load_unordered_access_resources(struct wined3d_context *context, + const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views) +{ + struct wined3d_unordered_access_view *view; + struct wined3d_texture *texture; + struct wined3d_buffer *buffer; + unsigned int i; + + context->uses_uavs = 0; + + if (!shader) + return; + + for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) { - if (!(shader = state->shader[shader_types[i].type])) + if (!(view = views[i])) continue; - count = shader->reg_maps.sampler_map.count; - if (count > shader_types[i].count) + if (view->resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Shader %p needs %u samplers, but only %u are supported.\n", - shader, count, shader_types[i].count); - count = shader_types[i].count; + buffer = buffer_from_resource(view->resource); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); + wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); + } + else + { + texture = texture_from_resource(view->resource); + wined3d_texture_load(texture, context, FALSE); + wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_TEXTURE_RGB); } - for (j = 0; j < count; ++j) + context->uses_uavs = 1; + } +} + +static void context_bind_unordered_access_views(struct wined3d_context *context, + const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_unordered_access_view *view; + GLuint texture_name; + unsigned int i; + GLint level; + + if (!shader) + return; + + for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) + { + if (!(view = views[i])) { - entry = &shader->reg_maps.sampler_map.entries[j]; - - if (!(view = state->shader_resource_view[shader_types[i].type][entry->resource_idx])) - { - WARN("No resource view bound at index %u, %u.\n", shader_types[i].type, entry->resource_idx); - continue; - } - - if (view->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Buffer shader resources not supported.\n"); - continue; - } - - if (entry->sampler_idx == WINED3D_SAMPLER_DEFAULT) - { - sampler_name = device->default_sampler; - } - else if ((sampler = state->sampler[shader_types[i].type][entry->sampler_idx])) - { - sampler_name = sampler->name; - } - else - { - WARN("No sampler object bound at index %u, %u.\n", shader_types[i].type, entry->sampler_idx); - continue; - } - - texture = wined3d_texture_from_resource(view->resource); - context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx); - wined3d_texture_bind(texture, context, FALSE); - - GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler_name)); - checkGLcall("glBindSampler"); + if (shader->reg_maps.uav_resource_info[i].type) + WARN("No unordered access view bound at index %u.\n", i); + GL_EXTCALL(glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8)); + continue; } + + if (view->gl_view.name) + { + texture_name = view->gl_view.name; + level = 0; + } + else if (view->resource->type != WINED3D_RTYPE_BUFFER) + { + struct wined3d_texture *texture = texture_from_resource(view->resource); + texture_name = wined3d_texture_get_texture_name(texture, context, FALSE); + level = view->desc.u.texture.level_idx; + } + else + { + FIXME("Unsupported buffer unordered access view.\n"); + GL_EXTCALL(glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8)); + continue; + } + + GL_EXTCALL(glBindImageTexture(i, texture_name, level, GL_TRUE, 0, GL_READ_WRITE, + view->format->glInternal)); + + if (view->counter_bo) + GL_EXTCALL(glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i, view->counter_bo)); + } + checkGLcall("Bind unordered access views"); +} + +static void context_load_stream_output_buffers(struct wined3d_context *context, + const struct wined3d_state *state) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) + { + struct wined3d_buffer *buffer; + if (!(buffer = state->stream_output[i].buffer)) + continue; + + wined3d_buffer_load(buffer, context, state); + wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER); } } /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, - const struct wined3d_state *state) +BOOL context_apply_draw_state(struct wined3d_context *context, + const struct wined3d_device *device, const struct wined3d_state *state) { const struct StateEntry *state_table = context->state_table; - const struct wined3d_fb_state *fb = &state->fb; -#else /* STAGING_CSMT */ -BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) -{ - const struct wined3d_state *state = &device->state; - const struct StateEntry *state_table = context->state_table; + const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_fb_state *fb = state->fb; -#endif /* STAGING_CSMT */ unsigned int i; WORD map; - if (!context_validate_rt_config(context->gl_info->limits.buffers, - fb->render_targets, fb->depth_stencil)) + if (!context_validate_rt_config(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) return FALSE; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER)) @@ -3236,9 +3817,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de * updating a resource location. */ context_update_tex_unit_map(context, state); context_preload_textures(context, state); - context_load_shader_resources(context, state); + context_load_shader_resources(context, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); + context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_PIXEL], + state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); + context_load_stream_output_buffers(context, state); /* TODO: Right now the dependency on the vertex shader is necessary - * since context_stream_info_from_declaration depends on the reg_maps of + * since wined3d_stream_info_from_declaration() depends on the reg_maps of * the current VS but maybe it's possible to relax the coupling in some * situations at least. */ if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC) @@ -3251,24 +3835,19 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) { if (map & 1) -#if defined(STAGING_CSMT) - buffer_internal_preload(state->streams[context->stream_info.elements[i].stream_idx].buffer, + wined3d_buffer_load(state->streams[context->stream_info.elements[i].stream_idx].buffer, context, state); } - /* PreLoad may kick buffers out of vram. */ + /* Loading the buffers above may have invalidated the stream info. */ if (isStateDirty(context, STATE_STREAMSRC)) context_update_stream_info(context, state); -#else /* STAGING_CSMT */ - buffer_mark_used(state->streams[context->stream_info.elements[i].stream_idx].buffer); - } -#endif /* STAGING_CSMT */ } if (state->index_buffer) { if (context->stream_info.all_vbo) - buffer_internal_preload(state->index_buffer, context, state); + wined3d_buffer_load(state->index_buffer, context, state); else - buffer_get_sysmem(state->index_buffer, context); + wined3d_buffer_load_sysmem(state->index_buffer, context); } for (i = 0; i < context->numDirtyEntries; ++i) @@ -3280,10 +3859,10 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de state_table[rep].apply(context, state, rep); } - if (context->shader_update_mask) + if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) { device->shader_backend->shader_select(device->shader_priv, context, state); - context->shader_update_mask = 0; + context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; } if (context->constant_update_mask) @@ -3294,8 +3873,20 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de if (context->update_shader_resource_bindings) { - context_bind_shader_resources(context, state); + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + context_bind_shader_resources(context, state, i); context->update_shader_resource_bindings = 0; + if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) + context->update_compute_shader_resource_bindings = 1; + } + + if (context->update_unordered_access_view_bindings) + { + context_bind_unordered_access_views(context, + state->shader[WINED3D_SHADER_TYPE_PIXEL], + state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); + context->update_unordered_access_view_bindings = 0; + context->update_compute_unordered_access_view_bindings = 1; } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) @@ -3309,34 +3900,97 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de return TRUE; } -static void context_setup_target(struct wined3d_context *context, struct wined3d_surface *target) +void context_apply_compute_state(struct wined3d_context *context, + const struct wined3d_device *device, const struct wined3d_state *state) +{ + const struct StateEntry *state_table = context->state_table; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int state_id, i, j; + + context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE); + context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_COMPUTE], + state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); + + for (i = 0, state_id = STATE_COMPUTE_OFFSET; i < ARRAY_SIZE(context->dirty_compute_states); ++i) + { + for (j = 0; j < sizeof(*context->dirty_compute_states) * CHAR_BIT; ++j, ++state_id) + { + if (context->dirty_compute_states[i] & (1u << j)) + state_table[state_id].apply(context, state, state_id); + } + } + memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states)); + + if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE)) + { + device->shader_backend->shader_select_compute(device->shader_priv, context, state); + context->shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE); + } + + if (context->update_compute_shader_resource_bindings) + { + context_bind_shader_resources(context, state, WINED3D_SHADER_TYPE_COMPUTE); + context->update_compute_shader_resource_bindings = 0; + if (gl_info->limits.combined_samplers == gl_info->limits.graphics_samplers) + context->update_shader_resource_bindings = 1; + } + + if (context->update_compute_unordered_access_view_bindings) + { + context_bind_unordered_access_views(context, + state->shader[WINED3D_SHADER_TYPE_COMPUTE], + state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); + context->update_compute_unordered_access_view_bindings = 0; + context->update_unordered_access_view_bindings = 1; + } + + context->last_was_blit = FALSE; +} + +void context_end_transform_feedback(struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + if (context->transform_feedback_active) + { + GL_EXTCALL(glEndTransformFeedback()); + checkGLcall("glEndTransformFeedback"); + context->transform_feedback_active = 0; + context->transform_feedback_paused = 0; + } +} + +static void context_setup_target(struct wined3d_context *context, + struct wined3d_texture *texture, unsigned int sub_resource_idx) { BOOL old_render_offscreen = context->render_offscreen, render_offscreen; - render_offscreen = wined3d_resource_is_offscreen(&target->container->resource); - if (context->current_rt == target && render_offscreen == old_render_offscreen) return; + render_offscreen = wined3d_resource_is_offscreen(&texture->resource); + if (context->current_rt.texture == texture + && context->current_rt.sub_resource_idx == sub_resource_idx + && render_offscreen == old_render_offscreen) + return; /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers * the alpha blend state changes with different render target formats. */ - if (!context->current_rt) + if (!context->current_rt.texture) { context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); } else { - const struct wined3d_format *old = context->current_rt->resource.format; - const struct wined3d_format *new = target->resource.format; + const struct wined3d_format *old = context->current_rt.texture->resource.format; + const struct wined3d_format *new = texture->resource.format; if (old->id != new->id) { /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size) - || !(target->container->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) + || !(texture->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE)); /* Update sRGB writing when switching between formats that do/do not support sRGB writing */ - if ((context->current_rt->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE) - != (target->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)) + if ((context->current_rt.texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE) + != (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)) context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); } @@ -3348,63 +4002,70 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d * has to be called with the old rendertarget active, otherwise a * wrong drawable is read. */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && old_render_offscreen && context->current_rt != target) + && old_render_offscreen && (context->current_rt.texture != texture + || context->current_rt.sub_resource_idx != sub_resource_idx)) { - struct wined3d_texture *texture = context->current_rt->container; + unsigned int prev_sub_resource_idx = context->current_rt.sub_resource_idx; + struct wined3d_texture *prev_texture = context->current_rt.texture; /* Read the back buffer of the old drawable into the destination texture. */ - if (texture->texture_srgb.name) - wined3d_texture_load(texture, context, TRUE); - wined3d_texture_load(texture, context, FALSE); -#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&context->current_rt->resource, WINED3D_LOCATION_DRAWABLE); -#else /* STAGING_CSMT */ - surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE); -#endif /* STAGING_CSMT */ + if (prev_texture->texture_srgb.name) + wined3d_texture_load(prev_texture, context, TRUE); + wined3d_texture_load(prev_texture, context, FALSE); + wined3d_texture_invalidate_location(prev_texture, prev_sub_resource_idx, WINED3D_LOCATION_DRAWABLE); } } - context->current_rt = target; + context->current_rt.texture = texture; + context->current_rt.sub_resource_idx = sub_resource_idx; context_set_render_offscreen(context, render_offscreen); } -struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target) +struct wined3d_context *context_acquire(const struct wined3d_device *device, + struct wined3d_texture *texture, unsigned int sub_resource_idx) { struct wined3d_context *current_context = context_get_current(); struct wined3d_context *context; + BOOL swapchain_texture; - TRACE("device %p, target %p.\n", device, target); + TRACE("device %p, texture %p, sub_resource_idx %u.\n", device, texture, sub_resource_idx); + + wined3d_from_cs(device->cs); if (current_context && current_context->destroyed) current_context = NULL; - if (!target) + swapchain_texture = texture && texture->swapchain; + if (!texture) { if (current_context - && current_context->current_rt - && current_context->swapchain->device == device) + && current_context->current_rt.texture + && current_context->device == device) { - target = current_context->current_rt; + texture = current_context->current_rt.texture; + sub_resource_idx = current_context->current_rt.sub_resource_idx; } else { struct wined3d_swapchain *swapchain = device->swapchains[0]; + if (swapchain->back_buffers) - target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); + texture = swapchain->back_buffers[0]; else - target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); + texture = swapchain->front_buffer; + sub_resource_idx = 0; } } - if (current_context && current_context->current_rt == target) + if (current_context && current_context->current_rt.texture == texture) { context = current_context; } - else if (target->container->swapchain) + else if (swapchain_texture) { TRACE("Rendering onscreen.\n"); - context = swapchain_get_context(target->container->swapchain); + context = swapchain_get_context(texture->swapchain); } else { @@ -3412,7 +4073,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str /* Stay with the current context if possible. Otherwise use the * context for the primary swapchain. */ - if (current_context && current_context->swapchain->device == device) + if (current_context && current_context->device == device) context = current_context; else context = swapchain_get_context(device->swapchains[0]); @@ -3420,8 +4081,9 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str context_enter(context); context_update_window(context); - context_setup_target(context, target); - if (!context->valid) return context; + context_setup_target(context, texture, sub_resource_idx); + if (!context->valid) + return context; if (context != current_context) { @@ -3435,3 +4097,18 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str return context; } + +struct wined3d_context *context_reacquire(const struct wined3d_device *device, + struct wined3d_context *context) +{ + struct wined3d_context *current_context; + + if (!context || context->tid != GetCurrentThreadId()) + return NULL; + + current_context = context_acquire(device, context->current_rt.texture, + context->current_rt.sub_resource_idx); + if (current_context != context) + ERR("Acquired context %p instead of %p.\n", current_context, context); + return current_context; +} diff --git a/reactos/dll/directx/wine/wined3d/cs.c b/reactos/dll/directx/wine/wined3d/cs.c index a80b72b4fe6..8818d9a0d38 100644 --- a/reactos/dll/directx/wine/wined3d/cs.c +++ b/reactos/dll/directx/wine/wined3d/cs.c @@ -20,21 +20,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#if defined(STAGING_CSMT) -enum wined3d_cs_op -{ - WINED3D_CS_OP_NOP, - WINED3D_CS_OP_SKIP, - WINED3D_CS_OP_FENCE, -#else /* STAGING_CSMT */ #define WINED3D_INITIAL_CS_SIZE 4096 enum wined3d_cs_op { -#endif /* STAGING_CSMT */ + WINED3D_CS_OP_NOP, WINED3D_CS_OP_PRESENT, WINED3D_CS_OP_CLEAR, + WINED3D_CS_OP_DISPATCH, WINED3D_CS_OP_DRAW, + WINED3D_CS_OP_FLUSH, WINED3D_CS_OP_SET_PREDICATION, WINED3D_CS_OP_SET_VIEWPORT, WINED3D_CS_OP_SET_SCISSOR_RECT, @@ -48,8 +43,10 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_CONSTANT_BUFFER, WINED3D_CS_OP_SET_TEXTURE, WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW, + WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SHADER, + WINED3D_CS_OP_SET_RASTERIZER_STATE, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, WINED3D_CS_OP_SET_SAMPLER_STATE, @@ -57,65 +54,34 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_CLIP_PLANE, WINED3D_CS_OP_SET_COLOR_KEY, WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, -#if defined(STAGING_CSMT) - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_VS_CONSTS_B, - WINED3D_CS_OP_SET_VS_CONSTS_I, - WINED3D_CS_OP_SET_PS_CONSTS_F, - WINED3D_CS_OP_SET_PS_CONSTS_B, - WINED3D_CS_OP_SET_PS_CONSTS_I, - WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, - WINED3D_CS_OP_SET_PRIMITIVE_TYPE, WINED3D_CS_OP_SET_LIGHT, WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_BLT, - WINED3D_CS_OP_CLEAR_RTV, - WINED3D_CS_OP_RESOURCE_CHANGED, - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_BUFFER_SWAP_MEM, - WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE, - WINED3D_CS_OP_BUFFER_PRELOAD, + WINED3D_CS_OP_PUSH_CONSTANTS, + WINED3D_CS_OP_RESET_STATE, + WINED3D_CS_OP_CALLBACK, WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_TEXTURE_PRELOAD, - WINED3D_CS_OP_UPDATE_TEXTURE, - WINED3D_CS_OP_EVICT_RESOURCE, - WINED3D_CS_OP_VIEW_DESTROY, - WINED3D_CS_OP_VDECL_DESTROY, - WINED3D_CS_OP_SHADER_CLEANUP, - WINED3D_CS_OP_CREATE_VBO, - WINED3D_CS_OP_RESOURCE_CLEANUP, - WINED3D_CS_OP_BUFFER_CLEANUP, - WINED3D_CS_OP_VOLUME_CLEANUP, - WINED3D_CS_OP_SURFACE_CLEANUP, - WINED3D_CS_OP_TEXTURE_CLEANUP, - WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, - WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, - WINED3D_CS_OP_DELETE_GL_CONTEXTS, - WINED3D_CS_OP_GETDC, - WINED3D_CS_OP_RELEASEDC, - WINED3D_CS_OP_SAMPLER_DESTROY, + WINED3D_CS_OP_PRELOAD_RESOURCE, + WINED3D_CS_OP_UNLOAD_RESOURCE, + WINED3D_CS_OP_MAP, + WINED3D_CS_OP_UNMAP, + WINED3D_CS_OP_BLT_SUB_RESOURCE, WINED3D_CS_OP_UPDATE_SUB_RESOURCE, + WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION, + WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_STOP, }; -struct wined3d_cs_stop +struct wined3d_cs_packet +{ + size_t size; + BYTE data[1]; +}; + +struct wined3d_cs_nop { enum wined3d_cs_op opcode; }; -struct wined3d_cs_fence -{ - enum wined3d_cs_op opcode; - BOOL *signalled; -}; - -#define CS_PRESENT_SRC_RECT 1 -#define CS_PRESENT_DST_RECT 2 -#define CS_PRESENT_DIRTY_RGN 4 struct wined3d_cs_present { enum wined3d_cs_op opcode; @@ -123,56 +89,49 @@ struct wined3d_cs_present struct wined3d_swapchain *swapchain; RECT src_rect; RECT dst_rect; - RGNDATA dirty_region; DWORD flags; - DWORD set_data; }; struct wined3d_cs_clear { enum wined3d_cs_op opcode; - DWORD rect_count; DWORD flags; + unsigned int rt_count; + struct wined3d_fb_state *fb; + RECT draw_rect; struct wined3d_color color; float depth; DWORD stencil; + unsigned int rect_count; RECT rects[1]; -#else /* STAGING_CSMT */ }; -struct wined3d_cs_present +struct wined3d_cs_dispatch { enum wined3d_cs_op opcode; - HWND dst_window_override; - struct wined3d_swapchain *swapchain; - const RECT *src_rect; - const RECT *dst_rect; - const RGNDATA *dirty_region; - DWORD flags; -}; - -struct wined3d_cs_clear -{ - enum wined3d_cs_op opcode; - DWORD rect_count; - const RECT *rects; - DWORD flags; - const struct wined3d_color *color; - float depth; - DWORD stencil; -#endif /* STAGING_CSMT */ + unsigned int group_count_x; + unsigned int group_count_y; + unsigned int group_count_z; }; struct wined3d_cs_draw { enum wined3d_cs_op opcode; - UINT start_idx; - UINT index_count; - UINT start_instance; - UINT instance_count; + GLenum primitive_type; + GLint patch_vertex_count; + int base_vertex_idx; + unsigned int start_idx; + unsigned int index_count; + unsigned int start_instance; + unsigned int instance_count; BOOL indexed; }; +struct wined3d_cs_flush +{ + enum wined3d_cs_op opcode; +}; + struct wined3d_cs_set_predication { enum wined3d_cs_op opcode; @@ -183,7 +142,6 @@ struct wined3d_cs_set_predication struct wined3d_cs_set_viewport { enum wined3d_cs_op opcode; -#if defined(STAGING_CSMT) struct wined3d_viewport viewport; }; @@ -191,15 +149,6 @@ struct wined3d_cs_set_scissor_rect { enum wined3d_cs_op opcode; RECT rect; -#else /* STAGING_CSMT */ - const struct wined3d_viewport *viewport; -}; - -struct wined3d_cs_set_scissor_rect -{ - enum wined3d_cs_op opcode; - const RECT *rect; -#endif /* STAGING_CSMT */ }; struct wined3d_cs_set_rendertarget_view @@ -251,6 +200,7 @@ struct wined3d_cs_set_index_buffer enum wined3d_cs_op opcode; struct wined3d_buffer *buffer; enum wined3d_format_id format_id; + unsigned int offset; }; struct wined3d_cs_set_constant_buffer @@ -285,6 +235,14 @@ struct wined3d_cs_set_shader_resource_view struct wined3d_shader_resource_view *view; }; +struct wined3d_cs_set_unordered_access_view +{ + enum wined3d_cs_op opcode; + enum wined3d_pipeline pipeline; + unsigned int view_idx; + struct wined3d_unordered_access_view *view; +}; + struct wined3d_cs_set_sampler { enum wined3d_cs_op opcode; @@ -300,6 +258,12 @@ struct wined3d_cs_set_shader struct wined3d_shader *shader; }; +struct wined3d_cs_set_rasterizer_state +{ + enum wined3d_cs_op opcode; + struct wined3d_rasterizer_state *state; +}; + struct wined3d_cs_set_render_state { enum wined3d_cs_op opcode; @@ -327,7 +291,6 @@ struct wined3d_cs_set_transform { enum wined3d_cs_op opcode; enum wined3d_transform_state state; -#if defined(STAGING_CSMT) struct wined3d_matrix matrix; }; @@ -342,66 +305,6 @@ struct wined3d_cs_set_material { enum wined3d_cs_op opcode; struct wined3d_material material; -#else /* STAGING_CSMT */ - const struct wined3d_matrix *matrix; -}; - -struct wined3d_cs_set_clip_plane -{ - enum wined3d_cs_op opcode; - UINT plane_idx; - const struct wined3d_vec4 *plane; -}; - -struct wined3d_cs_set_material -{ - enum wined3d_cs_op opcode; - const struct wined3d_material *material; -#endif /* STAGING_CSMT */ -}; - -struct wined3d_cs_reset_state -{ - enum wined3d_cs_op opcode; -}; - -#if defined(STAGING_CSMT) -struct wined3d_cs_set_consts_f -{ - enum wined3d_cs_op opcode; - UINT start_register, vector4f_count; - float constants[4]; -}; - -struct wined3d_cs_set_consts_b -{ - enum wined3d_cs_op opcode; - UINT start_register, bool_count; - BOOL constants[1]; -}; - -struct wined3d_cs_set_consts_i -{ - enum wined3d_cs_op opcode; - UINT start_register, vector4i_count; - int constants[4]; -}; - -struct wined3d_cs_finish -{ - enum wined3d_cs_op opcode; -}; - -struct wined3d_cs_set_base_vertex_index -{ - enum wined3d_cs_op opcode; - UINT base_vertex_index; -}; - -struct wined3d_cs_set_primitive_type -{ - enum wined3d_cs_op opcode; - GLenum gl_primitive_type; }; struct wined3d_cs_set_light @@ -413,70 +316,29 @@ struct wined3d_cs_set_light struct wined3d_cs_set_light_enable { enum wined3d_cs_op opcode; - UINT idx; + unsigned int idx; BOOL enable; }; -struct wined3d_cs_blt +struct wined3d_cs_push_constants { enum wined3d_cs_op opcode; - struct wined3d_surface *dst_surface; - RECT dst_rect; - struct wined3d_surface *src_surface; - RECT src_rect; - DWORD flags; - struct wined3d_blt_fx fx; - enum wined3d_texture_filter_type filter; + enum wined3d_push_constants type; + unsigned int start_idx; + unsigned int count; + BYTE constants[1]; }; -struct wined3d_cs_clear_rtv +struct wined3d_cs_reset_state { enum wined3d_cs_op opcode; - struct wined3d_rendertarget_view *view; - RECT rect; - struct wined3d_color color; }; -struct wined3d_cs_resource_map +struct wined3d_cs_callback { enum wined3d_cs_op opcode; - struct wined3d_resource *resource; - DWORD flags; - void **mem; -}; - -struct wined3d_cs_resource_unmap -{ - enum wined3d_cs_op opcode; - struct wined3d_resource *resource; -}; - -struct wined3d_cs_resource_changed -{ - enum wined3d_cs_op opcode; - struct wined3d_resource *resource; - struct wined3d_gl_bo *swap_buffer; - void *swap_heap_memory; -}; - -struct wined3d_cs_buffer_swap_mem -{ - enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; - BYTE *mem; -}; - -struct wined3d_cs_buffer_invalidate_bo_range -{ - enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; - UINT offset, size; -}; - -struct wined3d_cs_skip -{ - enum wined3d_cs_op opcode; - DWORD size; + void (*callback)(void *object); + void *object; }; struct wined3d_cs_query_issue @@ -486,415 +348,447 @@ struct wined3d_cs_query_issue DWORD flags; }; -struct wined3d_cs_query_destroy -{ - enum wined3d_cs_op opcode; - struct wined3d_query *query; -}; - -struct wined3d_cs_texture_preload -{ - enum wined3d_cs_op opcode; - struct wined3d_texture *texture; -}; - -struct wined3d_cs_update_texture -{ - enum wined3d_cs_op opcode; - struct wined3d_texture *src, *dst; -}; - -struct wined3d_cs_evict_resource +struct wined3d_cs_preload_resource { enum wined3d_cs_op opcode; struct wined3d_resource *resource; }; -struct wined3d_cs_buffer_preload -{ - enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; -}; - -struct wined3d_cs_view_destroy -{ - enum wined3d_cs_op opcode; - struct wined3d_rendertarget_view *view; -}; - -struct wined3d_cs_vertex_declaration_destroy -{ - enum wined3d_cs_op opcode; - struct wined3d_vertex_declaration *declaration; -}; - -struct wined3d_cs_shader_cleanup -{ - enum wined3d_cs_op opcode; - struct wined3d_shader *shader; -}; - -struct wined3d_cs_create_vbo -{ - enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; -}; - -struct wined3d_cs_resource_cleanup +struct wined3d_cs_unload_resource { enum wined3d_cs_op opcode; struct wined3d_resource *resource; }; -struct wined3d_cs_buffer_cleanup +struct wined3d_cs_map { enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; + struct wined3d_resource *resource; + unsigned int sub_resource_idx; + struct wined3d_map_desc *map_desc; + const struct wined3d_box *box; + DWORD flags; + HRESULT *hr; }; -struct wined3d_cs_volume_cleanup +struct wined3d_cs_unmap { enum wined3d_cs_op opcode; - struct wined3d_volume *volume; + struct wined3d_resource *resource; + unsigned int sub_resource_idx; + HRESULT *hr; }; -struct wined3d_cs_surface_cleanup +struct wined3d_cs_blt_sub_resource { enum wined3d_cs_op opcode; - struct wined3d_surface *surface; -}; - -struct wined3d_cs_texture_cleanup -{ - enum wined3d_cs_op opcode; - struct wined3d_texture *texture; -}; - -struct wined3d_cs_create_dummy_textures -{ - enum wined3d_cs_op opcode; -}; - -struct wined3d_cs_create_swapchain_context -{ - enum wined3d_cs_op opcode; - struct wined3d_swapchain *swapchain; - HRESULT *ret; -}; - -struct wined3d_cs_delete_gl_contexts -{ - enum wined3d_cs_op opcode; - struct wined3d_swapchain *swapchain; -}; - -struct wined3d_cs_getdc -{ - enum wined3d_cs_op opcode; - struct wined3d_surface *surface; -}; - -struct wined3d_cs_releasedc -{ - enum wined3d_cs_op opcode; - struct wined3d_surface *surface; -}; - -struct wined3d_cs_sampler_destroy -{ - enum wined3d_cs_op opcode; - struct wined3d_sampler *sampler; + struct wined3d_resource *dst_resource; + unsigned int dst_sub_resource_idx; + struct wined3d_box dst_box; + struct wined3d_resource *src_resource; + unsigned int src_sub_resource_idx; + struct wined3d_box src_box; + DWORD flags; + struct wined3d_blt_fx fx; + enum wined3d_texture_filter_type filter; }; struct wined3d_cs_update_sub_resource { enum wined3d_cs_op opcode; struct wined3d_resource *resource; - unsigned int sub_resource_idx, row_pitch, depth_pitch; - const struct wined3d_box *box; - const void *data; + unsigned int sub_resource_idx; + struct wined3d_box box; + struct wined3d_sub_resource_data data; +#if defined(STAGING_CSMT) + BYTE copy_data[1]; +#endif /* STAGING_CSMT */ }; -static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) +struct wined3d_cs_add_dirty_texture_region { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); - /* There is only one thread writing to queue.head, InterlockedExchange - * is used for the memory barrier. */ - InterlockedExchange(&cs->queue.head, new_val); + enum wined3d_cs_op opcode; + struct wined3d_texture *texture; + unsigned int layer; +}; - if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) - SetEvent(cs->event); +struct wined3d_cs_clear_unordered_access_view +{ + enum wined3d_cs_op opcode; + struct wined3d_unordered_access_view *view; + struct wined3d_uvec4 clear_value; +}; + +struct wined3d_cs_stop +{ + enum wined3d_cs_op opcode; +}; + +static void wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) +{ } -static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) -{ - LONG new_val = (cs->prio_queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); - /* There is only one thread writing to queue.head, InterlockedExchange - * is used for the memory barrier. */ - InterlockedExchange(&cs->prio_queue.head, new_val); - - if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) - SetEvent(cs->event); -} - -static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) -{ - return sizeof(enum wined3d_cs_op); -} - -static UINT wined3d_cs_exec_skip(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_skip *op = data; - - return op->size; -} - -static UINT wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_fence *op = data; - - InterlockedExchange(op->signalled, TRUE); - - return sizeof(*op); -} - -static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) -{ - struct wined3d_cs_fence *op; - - *signalled = FALSE; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_FENCE; - op->signalled = signalled; - cs->ops->submit(cs, sizeof(*op)); -} - -static void wined3d_cs_emit_fence_prio(struct wined3d_cs *cs, BOOL *signalled) -{ - struct wined3d_cs_fence *op; - - *signalled = FALSE; - - op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_FENCE; - op->signalled = signalled; - cs->ops->submit_prio(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_present *op = data; struct wined3d_swapchain *swapchain; - const RECT *src_rect = op->set_data & CS_PRESENT_SRC_RECT ? &op->src_rect : NULL; - const RECT *dst_rect = op->set_data & CS_PRESENT_DST_RECT ? &op->dst_rect : NULL; - const RGNDATA *dirty_region = op->set_data & CS_PRESENT_DIRTY_RGN ? &op->dirty_region : NULL; unsigned int i; swapchain = op->swapchain; wined3d_swapchain_set_window(swapchain, op->dst_window_override); - swapchain->swapchain_ops->swapchain_present(swapchain, - src_rect, dst_rect, dirty_region, op->flags, - wined3d_rendertarget_view_get_surface(cs->state.fb.depth_stencil)); + swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags); + + wined3d_resource_release(&swapchain->front_buffer->resource); + for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + { + wined3d_resource_release(&swapchain->back_buffers[i]->resource); + } InterlockedDecrement(&cs->pending_presents); - - wined3d_resource_dec_fence(&swapchain->front_buffer->resource); - for (i = 0; i < swapchain->desc.backbuffer_count; i++) - wined3d_resource_dec_fence(&swapchain->back_buffers[i]->resource); - - return sizeof(*op); } void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - const RGNDATA *dirty_region, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) { struct wined3d_cs_present *op; - LONG pending; unsigned int i; + LONG pending; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_PRESENT; op->dst_window_override = dst_window_override; op->swapchain = swapchain; - op->set_data = 0; - if (src_rect) - { - op->src_rect = *src_rect; - op->set_data |= CS_PRESENT_SRC_RECT; - } - if (dst_rect) - { - op->dst_rect = *dst_rect; - op->set_data |= CS_PRESENT_DST_RECT; - } - if (dirty_region) - { - op->dirty_region = *dirty_region; - op->set_data = CS_PRESENT_DIRTY_RGN; - } + op->src_rect = *src_rect; + op->dst_rect = *dst_rect; op->flags = flags; - wined3d_resource_inc_fence(&swapchain->front_buffer->resource); - for (i = 0; i < swapchain->desc.backbuffer_count; i++) - wined3d_resource_inc_fence(&swapchain->back_buffers[i]->resource); - pending = InterlockedIncrement(&cs->pending_presents); - cs->ops->submit(cs, sizeof(*op)); + wined3d_resource_acquire(&swapchain->front_buffer->resource); + for (i = 0; i < swapchain->desc.backbuffer_count; ++i) + { + wined3d_resource_acquire(&swapchain->back_buffers[i]->resource); + } - /* D3D10 documentation suggests that Windows allows the game to run - * 3 frames ahead of the GPU. Increasing this above 1 causes uneven - * animation in some games, most notably StarCraft II. The framerates - * don't show this problem. The issue is more noticable with vsync - * on, but also happens with vsync off. - * - * In Counter-Strike: Source a frame difference of 3 causes noticable - * input delay that makes the game unplayable. */ + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + + /* Limit input latency by limiting the number of presents that we can get + * ahead of the worker thread. We have a constant limit here, but + * IDXGIDevice1 allows tuning this. */ while (pending > 1) + { + wined3d_pause(); pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); + } } -static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) { + const struct wined3d_state *state = &cs->state; const struct wined3d_cs_clear *op = data; struct wined3d_device *device; + unsigned int i; RECT draw_rect; - unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0, i; device = cs->device; - wined3d_get_draw_rect(&cs->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, - &op->color, op->depth, op->stencil); + wined3d_get_draw_rect(state, &draw_rect); + device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb, + op->rect_count, op->rects, &op->draw_rect, op->flags, &op->color, op->depth, op->stencil); if (op->flags & WINED3DCLEAR_TARGET) { - for (i = 0; i < device->adapter->gl_info.limits.buffers; i++) + for (i = 0; i < op->rt_count; ++i) { - if (cs->state.fb.render_targets[i]) - wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); + if (op->fb->render_targets[i]) + wined3d_resource_release(op->fb->render_targets[i]->resource); } } if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); - - return sizeof(*op) + sizeof(*op->rects) * extra_rects; + wined3d_resource_release(op->fb->depth_stencil->resource); } void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - struct wined3d_cs_clear *op; - unsigned int extra_rects = rect_count ? rect_count - 1 : 0, i; - size_t size = sizeof(*op) + sizeof(*op->rects) * extra_rects; + unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers; const struct wined3d_state *state = &cs->device->state; + struct wined3d_cs_clear *op; + unsigned int i; - op = cs->ops->require_space(cs, size); + op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]), + WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_CLEAR; - op->rect_count = rect_count; - if (rect_count) - memcpy(op->rects, rects, rect_count * sizeof(*rects)); op->flags = flags; + op->rt_count = rt_count; + op->fb = &cs->fb; + wined3d_get_draw_rect(state, &op->draw_rect); op->color = *color; op->depth = depth; op->stencil = stencil; + op->rect_count = rect_count; + memcpy(op->rects, rects, sizeof(*rects) * rect_count); if (flags & WINED3DCLEAR_TARGET) { - for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) + for (i = 0; i < rt_count; ++i) { - if (state->fb.render_targets[i]) - wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); + if (state->fb->render_targets[i]) + wined3d_resource_acquire(state->fb->render_targets[i]->resource); } } if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_inc_fence(state->fb.depth_stencil->resource); + wined3d_resource_acquire(state->fb->depth_stencil->resource); - cs->ops->submit(cs, size); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static inline BOOL wined3d_cs_colorwrite_enabled(const struct wined3d_state *state, unsigned int i) +void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - switch (i) + struct wined3d_cs_clear *op; + struct { - case 0: - return !!state->render_states[WINED3D_RS_COLORWRITEENABLE]; - case 1: - return !!state->render_states[WINED3D_RS_COLORWRITEENABLE1]; - case 2: - return !!state->render_states[WINED3D_RS_COLORWRITEENABLE2]; - case 3: - return !!state->render_states[WINED3D_RS_COLORWRITEENABLE3]; - default: - ERR("Unexpected color target %u.\n", i); - return TRUE; + struct wined3d_rendertarget_view *rt; + struct wined3d_fb_state fb; + } *extra; + + op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(*extra), + WINED3D_CS_QUEUE_DEFAULT); + extra = (void *)&op->rects[1]; + extra->fb.render_targets = &extra->rt; + op->fb = &extra->fb; + + op->opcode = WINED3D_CS_OP_CLEAR; + op->flags = flags; + if (flags & WINED3DCLEAR_TARGET) + { + op->rt_count = 1; + op->fb->render_targets[0] = view; + op->fb->depth_stencil = NULL; + op->color = *color; } -} - -static inline BOOL wined3d_cs_depth_stencil_enabled(const struct wined3d_state *state) -{ - return state->render_states[WINED3D_RS_ZENABLE] - || state->render_states[WINED3D_RS_STENCILENABLE]; -} - -static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_draw *op = data; - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; - unsigned int i; - - if (op->indexed && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + else { - if (cs->state.load_base_vertex_index != cs->state.base_vertex_index) + op->rt_count = 0; + op->fb->render_targets[0] = NULL; + op->fb->depth_stencil = view; + op->depth = depth; + op->stencil = stencil; + } + SetRect(&op->draw_rect, 0, 0, view->width, view->height); + op->rect_count = 1; + op->rects[0] = *rect; + + wined3d_resource_acquire(view->resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void acquire_shader_resources(const struct wined3d_state *state, unsigned int shader_mask) +{ + struct wined3d_shader_sampler_map_entry *entry; + struct wined3d_shader_resource_view *view; + struct wined3d_shader *shader; + unsigned int i, j; + + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + if (!(shader_mask & (1u << i))) + continue; + + if (!(shader = state->shader[i])) + continue; + + for (j = 0; j < WINED3D_MAX_CBS; ++j) { - cs->state.load_base_vertex_index = cs->state.base_vertex_index; - device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); + if (state->cb[i][j]) + wined3d_resource_acquire(&state->cb[i][j]->resource); + } + + for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) + { + entry = &shader->reg_maps.sampler_map.entries[j]; + + if (!(view = state->shader_resource_view[i][entry->resource_idx])) + continue; + + wined3d_resource_acquire(view->resource); } } - else if (cs->state.load_base_vertex_index) +} + +static void release_shader_resources(const struct wined3d_state *state, unsigned int shader_mask) +{ + struct wined3d_shader_sampler_map_entry *entry; + struct wined3d_shader_resource_view *view; + struct wined3d_shader *shader; + unsigned int i, j; + + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { - cs->state.load_base_vertex_index = 0; + if (!(shader_mask & (1u << i))) + continue; + + if (!(shader = state->shader[i])) + continue; + + for (j = 0; j < WINED3D_MAX_CBS; ++j) + { + if (state->cb[i][j]) + wined3d_resource_release(&state->cb[i][j]->resource); + } + + for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) + { + entry = &shader->reg_maps.sampler_map.entries[j]; + + if (!(view = state->shader_resource_view[i][entry->resource_idx])) + continue; + + wined3d_resource_release(view->resource); + } + } +} + +static void acquire_unordered_access_resources(const struct wined3d_shader *shader, + struct wined3d_unordered_access_view * const *views) +{ + unsigned int i; + + if (!shader) + return; + + for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) + { + if (!shader->reg_maps.uav_resource_info[i].type) + continue; + + if (!views[i]) + continue; + + wined3d_resource_acquire(views[i]->resource); + } +} + +static void release_unordered_access_resources(const struct wined3d_shader *shader, + struct wined3d_unordered_access_view * const *views) +{ + unsigned int i; + + if (!shader) + return; + + for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) + { + if (!shader->reg_maps.uav_resource_info[i].type) + continue; + + if (!views[i]) + continue; + + wined3d_resource_release(views[i]->resource); + } +} + +static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_dispatch *op = data; + struct wined3d_state *state = &cs->state; + + dispatch_compute(cs->device, state, + op->group_count_x, op->group_count_y, op->group_count_z); + + release_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE); + release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE], + state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); +} + +void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) +{ + const struct wined3d_state *state = &cs->device->state; + struct wined3d_cs_dispatch *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_DISPATCH; + op->group_count_x = group_count_x; + op->group_count_y = group_count_y; + op->group_count_z = group_count_z; + + acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE); + acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE], + state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) +{ + struct wined3d_state *state = &cs->state; + const struct wined3d_cs_draw *op = data; + unsigned int i; + + if (!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] + && state->load_base_vertex_index != op->base_vertex_idx) + { + state->load_base_vertex_index = op->base_vertex_idx; device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); } - draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); + if (state->gl_primitive_type != op->primitive_type) + { + if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS) + device_invalidate_state(cs->device, STATE_POINT_ENABLE); + state->gl_primitive_type = op->primitive_type; + } + state->gl_patch_vertices = op->patch_vertex_count; + + draw_primitive(cs->device, state, op->base_vertex_idx, op->start_idx, + op->index_count, op->start_instance, op->instance_count, op->indexed); if (op->indexed) - wined3d_resource_dec_fence(&cs->state.index_buffer->resource); - for (i = 0; i < sizeof(cs->state.streams) / sizeof(*cs->state.streams); i++) + wined3d_resource_release(&state->index_buffer->resource); + for (i = 0; i < ARRAY_SIZE(state->streams); ++i) { - if (cs->state.streams[i].buffer) - wined3d_resource_dec_fence(&cs->state.streams[i].buffer->resource); + if (state->streams[i].buffer) + wined3d_resource_release(&state->streams[i].buffer->resource); } - for (i = 0; i < sizeof(cs->state.textures) / sizeof(*cs->state.textures); i++) + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) { - if (cs->state.textures[i]) - wined3d_resource_dec_fence(&cs->state.textures[i]->resource); + if (state->stream_output[i].buffer) + wined3d_resource_release(&state->stream_output[i].buffer->resource); } - for (i = 0; i < gl_info->limits.buffers; i++) + for (i = 0; i < ARRAY_SIZE(state->textures); ++i) { - if (cs->state.fb.render_targets[i] && wined3d_cs_colorwrite_enabled(&cs->state, i)) - wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); + if (state->textures[i]) + wined3d_resource_release(&state->textures[i]->resource); } - if (cs->state.fb.depth_stencil && wined3d_cs_depth_stencil_enabled(&cs->state)) - wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); - - return sizeof(*op); + for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i) + { + if (state->fb->render_targets[i]) + wined3d_resource_release(state->fb->render_targets[i]->resource); + } + if (state->fb->depth_stencil) + wined3d_resource_release(state->fb->depth_stencil->resource); + release_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); + release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL], + state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); } -void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, - UINT start_instance, UINT instance_count, BOOL indexed) +void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count, + int base_vertex_idx, unsigned int start_idx, unsigned int index_count, + unsigned int start_instance, unsigned int instance_count, BOOL indexed) { + const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_draw *op; unsigned int i; - const struct wined3d_state *state = &cs->device->state; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DRAW; + op->primitive_type = primitive_type; + op->patch_vertex_count = patch_vertex_count; + op->base_vertex_idx = base_vertex_idx; op->start_idx = start_idx; op->index_count = index_count; op->start_instance = start_instance; @@ -902,2025 +796,53 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun op->indexed = indexed; if (indexed) - { - wined3d_resource_inc_fence(&state->index_buffer->resource); - state->index_buffer->ignore_discard = FALSE; - } - for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) + wined3d_resource_acquire(&state->index_buffer->resource); + for (i = 0; i < ARRAY_SIZE(state->streams); ++i) { if (state->streams[i].buffer) - { - wined3d_resource_inc_fence(&state->streams[i].buffer->resource); - state->streams[i].buffer->ignore_discard = FALSE; - } + wined3d_resource_acquire(&state->streams[i].buffer->resource); } - for (i = 0; i < sizeof(state->textures) / sizeof(*state->textures); i++) + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) + { + if (state->stream_output[i].buffer) + wined3d_resource_acquire(&state->stream_output[i].buffer->resource); + } + for (i = 0; i < ARRAY_SIZE(state->textures); ++i) { if (state->textures[i]) - wined3d_resource_inc_fence(&state->textures[i]->resource); + wined3d_resource_acquire(&state->textures[i]->resource); } - for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) + for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i) { - if (state->fb.render_targets[i] && wined3d_cs_colorwrite_enabled(state, i)) - wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); + if (state->fb->render_targets[i]) + wined3d_resource_acquire(state->fb->render_targets[i]->resource); } - if (state->fb.depth_stencil && wined3d_cs_depth_stencil_enabled(state)) - wined3d_resource_inc_fence(state->fb.depth_stencil->resource); + if (state->fb->depth_stencil) + wined3d_resource_acquire(state->fb->depth_stencil->resource); + acquire_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); + acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL], + state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); - cs->ops->submit(cs, sizeof(*op)); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static UINT wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_flush(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_predication *op = data; - - cs->state.predicate = op->predicate; - cs->state.predicate_value = op->value; - - return sizeof(*op); -} - -void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) -{ - struct wined3d_cs_set_predication *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_PREDICATION; - op->predicate = predicate; - op->value = value; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_viewport *op = data; - struct wined3d_device *device = cs->device; - - cs->state.viewport = op->viewport; - device_invalidate_state(device, STATE_VIEWPORT); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) -{ - struct wined3d_cs_set_viewport *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_VIEWPORT; - op->viewport = *viewport; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_scissor_rect *op = data; - - cs->state.scissor_rect = op->rect; - device_invalidate_state(cs->device, STATE_SCISSORRECT); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) -{ - struct wined3d_cs_set_scissor_rect *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; - op->rect = *rect; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_rendertarget_view *op = data; - - cs->state.fb.render_targets[op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_FRAMEBUFFER); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, - struct wined3d_rendertarget_view *view) -{ - struct wined3d_cs_set_rendertarget_view *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; - op->view_idx = view_idx; - op->view = view; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_depth_stencil_view *op = data; - struct wined3d_device *device = cs->device; - struct wined3d_rendertarget_view *prev; - - if ((prev = cs->state.fb.depth_stencil)) - { - struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); - - if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || prev_surface->flags & SFLAG_DISCARD)) - { - surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); - if (prev_surface == cs->onscreen_depth_stencil) - { - wined3d_texture_decref(cs->onscreen_depth_stencil->container); - cs->onscreen_depth_stencil = NULL; - } - } - } - - cs->state.fb.depth_stencil = op->view; - - if (!prev != !op->view) - { - /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); - } - else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT) - != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT)) - { - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); - } - - device_invalidate_state(device, STATE_FRAMEBUFFER); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) -{ - struct wined3d_cs_set_depth_stencil_view *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; - op->view = view; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_vertex_declaration *op = data; - - cs->state.vertex_declaration = op->declaration; - device_invalidate_state(cs->device, STATE_VDECL); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) -{ - struct wined3d_cs_set_vertex_declaration *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; - op->declaration = declaration; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_stream_source *op = data; - struct wined3d_stream_state *stream; - struct wined3d_buffer *prev; - - stream = &cs->state.streams[op->stream_idx]; - prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; - stream->stride = op->stride; - - if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_STREAMSRC); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, - struct wined3d_buffer *buffer, UINT offset, UINT stride) -{ - struct wined3d_cs_set_stream_source *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; - op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; - op->stride = stride; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_stream_source_freq *op = data; - struct wined3d_stream_state *stream; - - stream = &cs->state.streams[op->stream_idx]; - stream->frequency = op->frequency; - stream->flags = op->flags; - - device_invalidate_state(cs->device, STATE_STREAMSRC); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) -{ - struct wined3d_cs_set_stream_source_freq *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; - op->stream_idx = stream_idx; - op->frequency = frequency; - op->flags = flags; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_stream_output *op = data; - struct wined3d_stream_output *stream; - struct wined3d_buffer *prev; - - stream = &cs->state.stream_output[op->stream_idx]; - prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; - - if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, - struct wined3d_buffer *buffer, UINT offset) -{ - struct wined3d_cs_set_stream_output *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; - op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_index_buffer *op = data; - struct wined3d_buffer *prev; - - prev = cs->state.index_buffer; - cs->state.index_buffer = op->buffer; - cs->state.index_format = op->format_id; - - if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_INDEXBUFFER); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, - enum wined3d_format_id format_id) -{ - struct wined3d_cs_set_index_buffer *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; - op->buffer = buffer; - op->format_id = format_id; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_constant_buffer *op = data; - struct wined3d_buffer *prev; - - prev = cs->state.cb[op->type][op->cb_idx]; - cs->state.cb[op->type][op->cb_idx] = op->buffer; - - if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type)); - return sizeof(*op); -} - -void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, - UINT cb_idx, struct wined3d_buffer *buffer) -{ - struct wined3d_cs_set_constant_buffer *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; - op->type = type; - op->cb_idx = cb_idx; - op->buffer = buffer; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; - const struct wined3d_cs_set_texture *op = data; - struct wined3d_texture *prev; - BOOL old_use_color_key = FALSE, new_use_color_key = FALSE; - - prev = cs->state.textures[op->stage]; - cs->state.textures[op->stage] = op->texture; - - if (op->texture) - { - const struct wined3d_format *new_format = op->texture->resource.format; - const struct wined3d_format *old_format = prev ? prev->resource.format : NULL; - unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0; - unsigned int new_fmt_flags = op->texture->resource.format_flags; - - if (InterlockedIncrement(&op->texture->resource.bind_count) == 1) - op->texture->sampler = op->stage; - - if (!prev || op->texture->target != prev->target - || !is_same_fixup(new_format->color_fixup, old_format->color_fixup) - || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)) - device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); - - if (!prev && op->stage < d3d_info->limits.ffp_blend_stages) - { - /* The source arguments for color and alpha ops have different - * meanings when a NULL texture is bound, so the COLOR_OP and - * ALPHA_OP have to be dirtified. */ - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); - } - - if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) - new_use_color_key = TRUE; - } - - if (prev) - { - if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage) - { - unsigned int i; - - /* Search for other stages the texture is bound to. Shouldn't - * happen if applications bind textures to a single stage only. */ - TRACE("Searching for other stages the texture is bound to.\n"); - for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) - { - if (cs->state.textures[i] == prev) - { - TRACE("Texture is also bound to stage %u.\n", i); - prev->sampler = i; - break; - } - } - } - - if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages) - { - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); - } - - if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT) - old_use_color_key = TRUE; - } - - device_invalidate_state(cs->device, STATE_SAMPLER(op->stage)); - - if (new_use_color_key != old_use_color_key) - device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); - - if (new_use_color_key) - device_invalidate_state(cs->device, STATE_COLOR_KEY); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) -{ - struct wined3d_cs_set_texture *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_TEXTURE; - op->stage = stage; - op->texture = texture; - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_shader_resource_view *op = data; - - cs->state.shader_resource_view[op->type][op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, - UINT view_idx, struct wined3d_shader_resource_view *view) -{ - struct wined3d_cs_set_shader_resource_view *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; - op->type = type; - op->view_idx = view_idx; - op->view = view; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_sampler *op = data; - - cs->state.sampler[op->type][op->sampler_idx] = op->sampler; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, - UINT sampler_idx, struct wined3d_sampler *sampler) -{ - struct wined3d_cs_set_sampler *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SAMPLER; - op->type = type; - op->sampler_idx = sampler_idx; - op->sampler = sampler; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_shader *op = data; - - cs->state.shader[op->type] = op->shader; - device_invalidate_state(cs->device, STATE_SHADER(op->type)); - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) -{ - struct wined3d_cs_set_shader *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SHADER; - op->type = type; - op->shader = shader; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_vs_consts_f(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_f *op = data; - struct wined3d_device *device = cs->device; - - memcpy(cs->state.vs_consts_f + op->start_register * 4, op->constants, - sizeof(*cs->state.vs_consts_f) * 4 * op->vector4f_count); - - device->shader_backend->shader_update_float_vertex_constants(device, - op->start_register, op->vector4f_count); - - return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); -} - -static UINT wined3d_cs_exec_set_ps_consts_f(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_f *op = data; - struct wined3d_device *device = cs->device; - - memcpy(cs->state.ps_consts_f + op->start_register * 4, op->constants, - sizeof(*cs->state.ps_consts_f) * 4 * op->vector4f_count); - - device->shader_backend->shader_update_float_pixel_constants(device, - op->start_register, op->vector4f_count); - - return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); -} - -void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, - const float *constants, UINT vector4f_count, enum wined3d_shader_type type) -{ - struct wined3d_cs_set_consts_f *op; - UINT extra_space = vector4f_count - 1; - size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - - op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: - op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_F; - break; - - case WINED3D_SHADER_TYPE_VERTEX: - op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_F; - break; - - case WINED3D_SHADER_TYPE_GEOMETRY: - FIXME("Invalid for geometry shaders\n"); - return; - - case WINED3D_SHADER_TYPE_COUNT: - break; - } - op->start_register = start_register; - op->vector4f_count = vector4f_count; - memcpy(op->constants, constants, sizeof(*constants) * 4 * vector4f_count); - - cs->ops->submit(cs, size); -} - -static UINT wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_render_state *op = data; - - cs->state.render_states[op->state] = op->value; - device_invalidate_state(cs->device, STATE_RENDER(op->state)); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) -{ - struct wined3d_cs_set_render_state *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; - op->state = state; - op->value = value; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_vs_consts_b(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_b *op = data; - struct wined3d_device *device = cs->device; - - memcpy(&cs->state.vs_consts_b[op->start_register], op->constants, - sizeof(*cs->state.vs_consts_b) * op->bool_count); - - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); - - return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); -} - -static UINT wined3d_cs_exec_set_ps_consts_b(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_b *op = data; - struct wined3d_device *device = cs->device; - - memcpy(&cs->state.ps_consts_b[op->start_register], op->constants, - sizeof(*cs->state.ps_consts_b) * op->bool_count); - - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); - - return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); -} - -void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) -{ - struct wined3d_cs_set_consts_b *op; - UINT extra_space = bool_count - 1; - size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - - op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: - op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_B; - break; - - case WINED3D_SHADER_TYPE_VERTEX: - op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_B; - break; - - case WINED3D_SHADER_TYPE_GEOMETRY: - FIXME("Invalid for geometry shaders\n"); - return; - - case WINED3D_SHADER_TYPE_COUNT: - break; - } - op->start_register = start_register; - op->bool_count = bool_count; - memcpy(op->constants, constants, sizeof(op->constants) * bool_count); - - cs->ops->submit(cs, size); -} - -static UINT wined3d_cs_exec_set_vs_consts_i(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_i *op = data; - struct wined3d_device *device = cs->device; - - memcpy(&cs->state.vs_consts_i[op->start_register * 4], op->constants, - sizeof(*cs->state.vs_consts_i) * 4 * op->vector4i_count); - - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); - - return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); -} - -static UINT wined3d_cs_exec_set_ps_consts_i(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_consts_i *op = data; - struct wined3d_device *device = cs->device; - - memcpy(&cs->state.ps_consts_i[op->start_register * 4], op->constants, - sizeof(*cs->state.ps_consts_i) * 4 * op->vector4i_count); - - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); - - return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); -} - -void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, - const int *constants, UINT vector4i_count, enum wined3d_shader_type type) -{ - struct wined3d_cs_set_consts_i *op; - UINT extra_space = vector4i_count - 1; - size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - - op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: - op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_I; - break; - - case WINED3D_SHADER_TYPE_VERTEX: - op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_I; - break; - - case WINED3D_SHADER_TYPE_GEOMETRY: - ERR("Invalid for geometry shaders\n"); - return; - - case WINED3D_SHADER_TYPE_COUNT: - break; - } - op->start_register = start_register; - op->vector4i_count = vector4i_count; - memcpy(op->constants, constants, sizeof(op->constants) * vector4i_count); - - cs->ops->submit(cs, size); -} - -static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_texture_state *op = data; - - cs->state.texture_states[op->stage][op->state] = op->value; - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, - enum wined3d_texture_stage_state state, DWORD value) -{ - struct wined3d_cs_set_texture_state *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; - op->stage = stage; - op->state = state; - op->value = value; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_sampler_state *op = data; - - cs->state.sampler_states[op->sampler_idx][op->state] = op->value; - device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, - enum wined3d_sampler_state state, DWORD value) -{ - struct wined3d_cs_set_sampler_state *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; - op->sampler_idx = sampler_idx; - op->state = state; - op->value = value; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_transform *op = data; - - cs->state.transforms[op->state] = op->matrix; - if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) - device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, - const struct wined3d_matrix *matrix) -{ - struct wined3d_cs_set_transform *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_TRANSFORM; - op->state = state; - op->matrix = *matrix; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_clip_plane *op = data; - - cs->state.clip_planes[op->plane_idx] = op->plane; - device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) -{ - struct wined3d_cs_set_clip_plane *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; - op->plane_idx = plane_idx; - op->plane = *plane; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_color_key *op = data; - struct wined3d_texture *texture = op->texture; - - if (op->set) - { - switch (op->flags) - { - case WINED3D_CKEY_DST_BLT: - texture->async.dst_blt_color_key = op->color_key; - texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT; - break; - - case WINED3D_CKEY_DST_OVERLAY: - texture->async.dst_overlay_color_key = op->color_key; - texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY; - break; - - case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0]) - { - device_invalidate_state(cs->device, STATE_COLOR_KEY); - if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) - device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); - } - - texture->async.src_blt_color_key = op->color_key; - texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT; - break; - - case WINED3D_CKEY_SRC_OVERLAY: - texture->async.src_overlay_color_key = op->color_key; - texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY; - break; - } - } - else - { - switch (op->flags) - { - case WINED3D_CKEY_DST_BLT: - texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT; - break; - - case WINED3D_CKEY_DST_OVERLAY: - texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY; - break; - - case WINED3D_CKEY_SRC_BLT: - if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) - device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); - - texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT; - break; - - case WINED3D_CKEY_SRC_OVERLAY: - texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY; - break; - } - } - - return sizeof(*op); -} - -void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, - WORD flags, const struct wined3d_color_key *color_key) -{ - struct wined3d_cs_set_color_key *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_COLOR_KEY; - op->texture = texture; - op->flags = flags; - if (color_key) - { - op->color_key = *color_key; - op->set = 1; - } - else - op->set = 0; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_material *op = data; - - cs->state.material = op->material; - device_invalidate_state(cs->device, STATE_MATERIAL); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) -{ - struct wined3d_cs_set_material *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_MATERIAL; - op->material = *material; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) -{ - struct wined3d_adapter *adapter = cs->device->adapter; - HRESULT hr; - - state_cleanup(&cs->state); - memset(&cs->state, 0, sizeof(cs->state)); - if (FAILED(hr = state_init(&cs->state, &adapter->gl_info, &adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize CS state, hr %#x.\n", hr); - - return sizeof(struct wined3d_cs_reset_state); -} - -void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) -{ - struct wined3d_cs_reset_state *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESET_STATE; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_finish *op = data; - struct wined3d_device *device = cs->device; struct wined3d_context *context; - if (!device->d3d_initialized) - return sizeof(*op); - - context = context_acquire(device, NULL); - context->gl_info->gl_ops.gl.p_glFinish(); + context = context_acquire(cs->device, NULL, 0); + context->gl_info->gl_ops.gl.p_glFlush(); context_release(context); - - return sizeof(*op); -} - -void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) -{ - struct wined3d_cs_finish *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_GLFINISH; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_base_vertex_index(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_base_vertex_index *op = data; - - cs->state.base_vertex_index = op->base_vertex_index; - device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); - - return sizeof(*op); -} - -void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) -{ - struct wined3d_cs_set_base_vertex_index *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_BASE_VERTEX_INDEX; - op->base_vertex_index = base_vertex_index; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_primitive_type *op = data; - GLenum prev; - - prev = cs->state.gl_primitive_type; - - if (op->gl_primitive_type == GL_POINTS || prev == GL_POINTS) - device_invalidate_state(cs->device, STATE_POINT_ENABLE); - - cs->state.gl_primitive_type = op->gl_primitive_type; - - return sizeof(*op); -} - -void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_type) -{ - struct wined3d_cs_set_primitive_type *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE; - op->gl_primitive_type = primitive_type; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_light *op = data; - - UINT light_idx = op->light.OriginalIndex; - UINT hash_idx = LIGHTMAP_HASHFUNC(op->light.OriginalIndex); - struct wined3d_light_info *object = NULL; - struct list *e; - - LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) - { - object = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (object->OriginalIndex == light_idx) - break; - object = NULL; - } - - if (!object) - { - TRACE("Adding new light\n"); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) - return E_OUTOFMEMORY; - - list_add_head(&cs->state.light_map[hash_idx], &object->entry); - object->glIndex = -1; - object->OriginalIndex = light_idx; - } - - /* Update the live definitions if the light is currently assigned a glIndex. */ - if (object->glIndex != -1) - { - if (object->OriginalParms.type != op->light.OriginalParms.type) - device_invalidate_state(cs->device, STATE_LIGHT_TYPE); - device_invalidate_state(cs->device, STATE_ACTIVELIGHT(object->glIndex)); - } - - object->OriginalParms = op->light.OriginalParms; - object->position = op->light.position; - object->direction = op->light.direction; - object->exponent = op->light.exponent; - object->cutoff = op->light.cutoff; - - return sizeof(*op); -} - -void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) -{ - struct wined3d_cs_set_light *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_LIGHT; - op->light = *light; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_light_enable *op = data; - UINT hash_idx = LIGHTMAP_HASHFUNC(op->idx); - struct wined3d_light_info *light_info = NULL; - struct list *e; - struct wined3d_device *device = cs->device; - - LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) - { - light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (light_info->OriginalIndex == op->idx) - break; - light_info = NULL; - } - TRACE("Found light %p.\n", light_info); - - /* Should be handled by the device by emitting a set_light op */ - if (!light_info) - { - ERR("Light enabled requested but light not defined in cs state!\n"); - return sizeof(*op); - } - - if (!op->enable) - { - if (light_info->glIndex != -1) - { - device_invalidate_state(device, STATE_LIGHT_TYPE); - device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); - cs->state.lights[light_info->glIndex] = NULL; - light_info->glIndex = -1; - } - else - { - TRACE("Light already disabled, nothing to do\n"); - } - light_info->enabled = FALSE; - } - else - { - light_info->enabled = TRUE; - if (light_info->glIndex != -1) - { - TRACE("Nothing to do as light was enabled\n"); - } - else - { - unsigned int i; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - /* Find a free GL light. */ - for (i = 0; i < gl_info->limits.lights; ++i) - { - if (!cs->state.lights[i]) - { - cs->state.lights[i] = light_info; - light_info->glIndex = i; - break; - } - } - if (light_info->glIndex == -1) - { - /* Should be caught by the device before emitting - * the light_enable op */ - ERR("Too many concurrently active lights in cs\n"); - return sizeof(*op); - } - - /* i == light_info->glIndex */ - device_invalidate_state(device, STATE_LIGHT_TYPE); - device_invalidate_state(device, STATE_ACTIVELIGHT(i)); - } - } - - return sizeof(*op); -} - -void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) -{ - struct wined3d_cs_set_light_enable *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_LIGHT_ENABLE; - op->idx = idx; - op->enable = enable; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_blt *op = data; - - surface_blt_ugly(op->dst_surface, &op->dst_rect, - op->src_surface, &op->src_rect, - op->flags, &op->fx, op->filter); - - wined3d_resource_dec_fence(&op->dst_surface->container->resource); - if (op->src_surface && op->src_surface != op->dst_surface) - wined3d_resource_dec_fence(&op->src_surface->container->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, - const RECT *dst_rect, struct wined3d_surface *src_surface, - const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, - enum wined3d_texture_filter_type filter) -{ - struct wined3d_cs_blt *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_BLT; - op->dst_surface = dst_surface; - op->dst_rect = *dst_rect; - op->src_surface = src_surface; - op->src_rect = *src_rect; - op->flags = flags; - op->filter = filter; - if (fx) - op->fx = *fx; - - wined3d_resource_inc_fence(&dst_surface->container->resource); - if (src_surface && src_surface != dst_surface) - wined3d_resource_inc_fence(&src_surface->container->resource); - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_clear_rtv *op = data; - struct wined3d_resource *resource = op->view->resource; - - resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), op->view->sub_resource_idx); - - surface_color_fill(surface_from_resource(resource), &op->rect, &op->color); - - wined3d_resource_dec_fence(op->view->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) -{ - struct wined3d_cs_clear_rtv *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_CLEAR_RTV; - op->view = view; - op->rect = *rect; - op->color = *color; - - wined3d_resource_inc_fence(view->resource); - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_resource_changed *op = data; - struct wined3d_resource *resource = op->resource; - - wined3d_resource_changed(resource, op->swap_buffer, op->swap_heap_memory); - - return sizeof(*op); -} - -void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, - struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) -{ - struct wined3d_cs_resource_changed *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; - op->resource = resource; - op->swap_buffer = swap_buffer; - op->swap_heap_memory = swap_heap_memory; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_resource_map *op = data; - - *op->mem = wined3d_resource_map_internal(op->resource, op->flags); - - return sizeof(*op); -} - -void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) -{ - struct wined3d_cs_resource_map *op; - void *ret; - - op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_MAP; - op->resource = resource; - op->flags = flags; - op->mem = &ret; - - cs->ops->submit_prio(cs, sizeof(*op)); - - cs->ops->finish_prio(cs); - - return ret; -} - -static UINT wined3d_cs_exec_resource_unmap(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_resource_unmap *op = data; - struct wined3d_resource *resource = op->resource; - - wined3d_resource_unmap_internal(resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) -{ - struct wined3d_cs_resource_unmap *op; - - op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; - op->resource = resource; - - cs->ops->submit_prio(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_query_issue *op = data; - struct wined3d_query *query = op->query; - BOOL poll; - - poll = query->query_ops->query_issue(query, op->flags); - - if (wined3d_settings.cs_multithreaded) - { - if (poll && list_empty(&query->poll_list_entry)) - { - list_add_tail(&cs->query_poll_list, &query->poll_list_entry); - } - else if (!poll && !list_empty(&query->poll_list_entry)) - { - /* Can happen if occlusion queries are restarted. This discards the old - * result, polling it could result in a GL error */ - list_remove(&query->poll_list_entry); - list_init(&query->poll_list_entry); - } - else if (op->flags & WINED3DISSUE_END) - { - /* Can happen when an occlusion query is ended without being started, - * in which case we don't want to poll, but still have to counter-balance - * the increment of the main counter (!poll && list_empty). - * - * This can also happen if an event query is re-issued before the first - * fence was reached (poll && !list_empty). In this case the query is - * already in the list and the poll function will check the new fence. - * We have to counter-balance the discarded increment. */ - InterlockedIncrement(&query->counter_retrieved); - } - } - - return sizeof(*op); -} - -void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) -{ - struct wined3d_cs_query_issue *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_QUERY_ISSUE; - op->query = query; - op->flags = flags; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_query_destroy(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_query_destroy *op = data; - - if (!list_empty(&op->query->poll_list_entry)) - list_remove(&op->query->poll_list_entry); - - wined3d_query_destroy(op->query); - - return sizeof(*op); -} - -void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) -{ - struct wined3d_cs_query_destroy *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_QUERY_DESTROY; - op->query = query; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_texture_preload *op = data; - struct wined3d_context *context; - struct wined3d_texture *texture = op->texture; - - context = context_acquire(cs->device, NULL); - wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); - context_release(context); - - wined3d_resource_dec_fence(&texture->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) -{ - struct wined3d_cs_texture_preload *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD; - op->texture = texture; - - wined3d_resource_inc_fence(&texture->resource); - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_update_texture(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_update_texture *op = data; - struct wined3d_context *context; - - context = context_acquire(cs->device, NULL); - device_exec_update_texture(context, op->src, op->dst); - context_release(context); - - wined3d_resource_dec_fence(&op->src->resource); - wined3d_resource_dec_fence(&op->dst->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, - struct wined3d_texture *dst) -{ - struct wined3d_cs_update_texture *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_UPDATE_TEXTURE; - op->src = src; - op->dst = dst; - - wined3d_resource_inc_fence(&op->src->resource); - wined3d_resource_inc_fence(&op->dst->resource); - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_evict_resource(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_evict_resource *op = data; - struct wined3d_resource *resource = op->resource; - - resource->resource_ops->resource_unload(resource); - - /* FIXME: Is this necessary? Bound buffers are preloaded anyway, and in theory - * PreLoad should take care of invalidating the state if the VBO changes */ - if (resource->bind_count && resource->type == WINED3D_RTYPE_BUFFER) - { - device_invalidate_state(cs->device, STATE_STREAMSRC); - device_invalidate_state(cs->device, STATE_INDEXBUFFER); - } - - return sizeof(*op); -} - -void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) -{ - struct wined3d_cs_evict_resource *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_EVICT_RESOURCE; - op->resource = resource; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_buffer_swap_mem(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_buffer_swap_mem *op = data; - struct wined3d_buffer *buffer = op->buffer; - - buffer_swap_mem(buffer, op->mem); - - if (!buffer->buffer_object && buffer->resource.bind_count) - { - device_invalidate_state(cs->device, STATE_STREAMSRC); - device_invalidate_state(cs->device, STATE_INDEXBUFFER); - } - return sizeof(*op); -} - -void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, BYTE *mem) -{ - struct wined3d_cs_buffer_swap_mem *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_BUFFER_SWAP_MEM; - op->buffer = buffer; - op->mem = mem; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_buffer_invalidate_bo_range(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_buffer_invalidate_bo_range *op = data; - - buffer_invalidate_bo_range(op->buffer, op->offset, op->size); - return sizeof(*op); -} - -void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - struct wined3d_buffer *buffer, UINT offset, UINT size) -{ - struct wined3d_cs_buffer_invalidate_bo_range *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE; - op->buffer = buffer; - op->offset = offset; - op->size = size; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_buffer_preload *op = data; - struct wined3d_context *context; - - context = context_acquire(cs->device, NULL); - buffer_internal_preload(op->buffer, context, NULL); - context_release(context); - - wined3d_resource_dec_fence(&op->buffer->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -{ - struct wined3d_cs_buffer_preload *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD; - op->buffer = buffer; - - wined3d_resource_inc_fence(&buffer->resource); - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_view_destroy(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_view_destroy *op = data; - - wined3d_rendertarget_view_destroy(op->view); - - return sizeof(*op); -} - -void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) -{ - struct wined3d_cs_view_destroy *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_VIEW_DESTROY; - op->view = view; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_vertex_declaration_destroy(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_vertex_declaration_destroy *op = data; - - wined3d_vertex_declaration_destroy(op->declaration); - - return sizeof(*op); -} - -void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) -{ - struct wined3d_cs_vertex_declaration_destroy *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_VDECL_DESTROY; - op->declaration = declaration; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_shader_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_shader_cleanup *op = data; - - shader_cleanup(op->shader); - HeapFree(GetProcessHeap(), 0, op->shader); - - return sizeof(*op); -} - -void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) -{ - struct wined3d_cs_shader_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SHADER_CLEANUP; - op->shader = shader; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_create_vbo(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_create_vbo *op = data; - struct wined3d_context *context = context_acquire(cs->device, NULL); - - buffer_create_buffer_object(op->buffer, context); - - context_release(context); - - return sizeof(*op); -} - -void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -{ - struct wined3d_cs_create_vbo *op; - - op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_CREATE_VBO; - op->buffer = buffer; - - cs->ops->submit_prio(cs, sizeof(*op)); - cs->ops->finish_prio(cs); -} - -static UINT wined3d_cs_exec_resource_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_resource_cleanup *op = data; - - wined3d_resource_cleanup_cs(op->resource); - - return sizeof(*op); -} - -void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, struct wined3d_resource *resource) -{ - struct wined3d_cs_resource_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_CLEANUP; - op->resource = resource; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_buffer_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_buffer_cleanup *op = data; - - wined3d_buffer_cleanup_cs(op->buffer); - - return sizeof(*op); -} - -void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -{ - struct wined3d_cs_buffer_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_BUFFER_CLEANUP; - op->buffer = buffer; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_volume_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_volume_cleanup *op = data; - - wined3d_volume_cleanup_cs(op->volume); - - return sizeof(*op); -} - -void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) -{ - struct wined3d_cs_volume_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_VOLUME_CLEANUP; - op->volume = volume; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_surface_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_surface_cleanup *op = data; - - wined3d_surface_cleanup_cs(op->surface); - - return sizeof(*op); -} - -void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) -{ - struct wined3d_cs_surface_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SURFACE_CLEANUP; - op->surface = surface; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_texture_cleanup(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_texture_cleanup *op = data; - - wined3d_texture_cleanup_cs(op->texture); - - return sizeof(*op); -} - -void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) -{ - struct wined3d_cs_texture_cleanup *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_TEXTURE_CLEANUP; - op->texture = texture; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_create_dummy_textures(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_create_dummy_textures *op = data; - struct wined3d_context *context = context_acquire(cs->device, NULL); - - device_create_dummy_textures(cs->device, context); - device_create_default_sampler(cs->device); - - context_release(context); - return sizeof(*op); -} - -void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) -{ - struct wined3d_cs_create_dummy_textures *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_CREATE_DUMMY_TEXTURES; - - cs->ops->submit(cs, sizeof(*op)); - cs->ops->finish(cs); -} - -static UINT wined3d_cs_exec_create_swapchain_context(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_create_swapchain_context *op = data; - - *op->ret = swapchain_create_context_cs(cs->device, op->swapchain); - - return sizeof(*op); -} - -HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) -{ - HRESULT ret; - struct wined3d_cs_create_swapchain_context *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT; - op->swapchain = swapchain; - op->ret = &ret; - - cs->ops->submit(cs, sizeof(*op)); - cs->ops->finish(cs); - - return ret; -} - -static UINT wined3d_cs_exec_delete_gl_contexts(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_delete_gl_contexts *op = data; - - device_delete_opengl_contexts_cs(cs->device, op->swapchain); - - return sizeof(*op); -} - -void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) -{ - struct wined3d_cs_delete_gl_contexts *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_DELETE_GL_CONTEXTS; - op->swapchain = swapchain; - - cs->ops->submit(cs, sizeof(*op)); - cs->ops->finish(cs); -} - -static UINT wined3d_cs_exec_getdc(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_getdc *op = data; - - wined3d_surface_getdc_cs(op->surface); - - return sizeof(*op); -} - -void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) -{ - struct wined3d_cs_getdc *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_GETDC; - op->surface = surface; - - cs->ops->submit(cs, sizeof(*op)); - cs->ops->finish(cs); -} - -static UINT wined3d_cs_exec_releasedc(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_releasedc *op = data; - - wined3d_surface_releasedc_cs(op->surface); - - return sizeof(*op); -} - -void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) -{ - struct wined3d_cs_releasedc *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RELEASEDC; - op->surface = surface; - - cs->ops->submit(cs, sizeof(*op)); - cs->ops->finish(cs); -} - -static UINT wined3d_cs_exec_sampler_destroy(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_sampler_destroy *op = data; - - wined3d_sampler_destroy(op->sampler); - - return sizeof(*op); -} - -void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) -{ - struct wined3d_cs_sampler_destroy *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SAMPLER_DESTROY; - op->sampler = sampler; - - cs->ops->submit(cs, sizeof(*op)); -} - -static UINT wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_update_sub_resource *op = data; - - struct wined3d_resource *sub_resource; - const struct wined3d_gl_info *gl_info; - struct wined3d_const_bo_address addr; - struct wined3d_context *context; - struct wined3d_texture *texture; - struct wined3d_surface *surface; - POINT dst_point; - RECT src_rect; - - texture = wined3d_texture_from_resource(op->resource); - sub_resource = wined3d_texture_get_sub_resource(texture, op->sub_resource_idx); - surface = surface_from_resource(sub_resource); - - src_rect.left = 0; - src_rect.top = 0; - if (op->box) - { - src_rect.right = op->box->right - op->box->left; - src_rect.bottom = op->box->bottom - op->box->top; - dst_point.x = op->box->left; - dst_point.y = op->box->top; - } - else - { - src_rect.right = sub_resource->width; - src_rect.bottom = sub_resource->height; - dst_point.x = 0; - dst_point.y = 0; - } - - addr.buffer_object = 0; - addr.addr = op->data; - - context = context_acquire(cs->device, NULL); - gl_info = context->gl_info; - - /* Only load the surface for partial updates. */ - if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width - && src_rect.bottom == sub_resource->height) - wined3d_texture_prepare_texture(texture, context, FALSE); - else - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - - wined3d_surface_upload_data(surface, gl_info, op->resource->format, - &src_rect, op->row_pitch, &dst_point, FALSE, &addr); - - context_release(context); - - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); - - return sizeof(*op); -} - -void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, - unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch) -{ - struct wined3d_cs_update_sub_resource *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; - op->resource = resource; - op->sub_resource_idx = sub_resource_idx; - op->box = box; - op->data = data; - op->row_pitch = row_pitch; - op->depth_pitch = depth_pitch; - - cs->ops->submit(cs, sizeof(*op)); - /* The data pointer may go away, need to wait until the data is read. Copying the data may be faster. - * Don't forget to copy box as well in this case. */ - cs->ops->finish(cs); -} - -static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = -{ - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, - /* WINED3D_CS_OP_SKIP */ wined3d_cs_exec_skip, - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -#else /* STAGING_CSMT */ -static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_present *op = data; - struct wined3d_swapchain *swapchain; - - swapchain = op->swapchain; - wined3d_swapchain_set_window(swapchain, op->dst_window_override); - - swapchain->swapchain_ops->swapchain_present(swapchain, - op->src_rect, op->dst_rect, op->dirty_region, op->flags); -} - -void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - const RGNDATA *dirty_region, DWORD flags) -{ - struct wined3d_cs_present *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_PRESENT; - op->dst_window_override = dst_window_override; - op->swapchain = swapchain; - op->src_rect = src_rect; - op->dst_rect = dst_rect; - op->dirty_region = dirty_region; - op->flags = flags; - - cs->ops->submit(cs); -} - -static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_clear *op = data; - struct wined3d_device *device; - RECT draw_rect; - - device = cs->device; - wined3d_get_draw_rect(&device->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, - op->color, op->depth, op->stencil); -} - -void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, - DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) -{ - struct wined3d_cs_clear *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_CLEAR; - op->rect_count = rect_count; - op->rects = rects; - op->flags = flags; - op->color = color; - op->depth = depth; - op->stencil = stencil; - - cs->ops->submit(cs); -} - -static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_draw *op = data; - - draw_primitive(cs->device, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); } -void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, - UINT start_instance, UINT instance_count, BOOL indexed) +void wined3d_cs_emit_flush(struct wined3d_cs *cs) { - struct wined3d_cs_draw *op; + struct wined3d_cs_flush *op; - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_DRAW; - op->start_idx = start_idx; - op->index_count = index_count; - op->start_instance = start_instance; - op->instance_count = instance_count; - op->indexed = indexed; + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_FLUSH; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) @@ -2935,19 +857,19 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query { struct wined3d_cs_set_predication *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_PREDICATION; op->predicate = predicate; op->value = value; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_viewport *op = data; - cs->state.viewport = *op->viewport; + cs->state.viewport = op->viewport; device_invalidate_state(cs->device, STATE_VIEWPORT); } @@ -2955,18 +877,18 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi { struct wined3d_cs_set_viewport *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_VIEWPORT; - op->viewport = viewport; + op->viewport = *viewport; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_scissor_rect *op = data; - cs->state.scissor_rect = *op->rect; + cs->state.scissor_rect = op->rect; device_invalidate_state(cs->device, STATE_SCISSORRECT); } @@ -2974,11 +896,11 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) { struct wined3d_cs_set_scissor_rect *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; - op->rect = rect; + op->rect = *rect; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) @@ -2994,12 +916,12 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v { struct wined3d_cs_set_rendertarget_view *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; op->view_idx = view_idx; op->view = view; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) @@ -3012,15 +934,11 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const { struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); - if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || prev_surface->flags & SFLAG_DISCARD)) + if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD)) { - surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); - if (prev_surface == device->onscreen_depth_stencil) - { - wined3d_texture_decref(device->onscreen_depth_stencil->container); - device->onscreen_depth_stencil = NULL; - } + wined3d_texture_validate_location(prev_surface->container, + prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED); } } @@ -3047,11 +965,11 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 { struct wined3d_cs_set_depth_stencil_view *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; op->view = view; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) @@ -3066,11 +984,11 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 { struct wined3d_cs_set_vertex_declaration *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; op->declaration = declaration; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) @@ -3098,14 +1016,14 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, { struct wined3d_cs_set_stream_source *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; op->stream_idx = stream_idx; op->buffer = buffer; op->offset = offset; op->stride = stride; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) @@ -3124,13 +1042,13 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i { struct wined3d_cs_set_stream_source_freq *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; op->stream_idx = stream_idx; op->frequency = frequency; op->flags = flags; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) @@ -3148,6 +1066,8 @@ static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void InterlockedIncrement(&op->buffer->resource.bind_count); if (prev) InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_STREAM_OUTPUT); } void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, @@ -3155,13 +1075,13 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, { struct wined3d_cs_set_stream_output *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; op->stream_idx = stream_idx; op->buffer = buffer; op->offset = offset; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) @@ -3172,6 +1092,7 @@ static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void * prev = cs->state.index_buffer; cs->state.index_buffer = op->buffer; cs->state.index_format = op->format_id; + cs->state.index_offset = op->offset; if (op->buffer) InterlockedIncrement(&op->buffer->resource.bind_count); @@ -3182,16 +1103,17 @@ static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void * } void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, - enum wined3d_format_id format_id) + enum wined3d_format_id format_id, unsigned int offset) { struct wined3d_cs_set_index_buffer *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; op->buffer = buffer; op->format_id = format_id; + op->offset = offset; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) @@ -3215,17 +1137,18 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha { struct wined3d_cs_set_constant_buffer *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; op->type = type; op->cb_idx = cb_idx; op->buffer = buffer; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) { + const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; const struct wined3d_cs_set_texture *op = data; struct wined3d_texture *prev; @@ -3245,7 +1168,8 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) op->texture->sampler = op->stage; if (!prev || op->texture->target != prev->target - || !is_same_fixup(new_format->color_fixup, old_format->color_fixup) + || (!is_same_fixup(new_format->color_fixup, old_format->color_fixup) + && !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format))) || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)) device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); @@ -3305,20 +1229,31 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined { struct wined3d_cs_set_texture *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TEXTURE; op->stage = stage; op->texture = texture; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_shader_resource_view *op = data; + struct wined3d_shader_resource_view *prev; + prev = cs->state.shader_resource_view[op->type][op->view_idx]; cs->state.shader_resource_view[op->type][op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); + + if (op->view) + InterlockedIncrement(&op->view->resource->bind_count); + if (prev) + InterlockedDecrement(&prev->resource->bind_count); + + if (op->type != WINED3D_SHADER_TYPE_COMPUTE) + device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + else + device_invalidate_state(cs->device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); } void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, @@ -3326,13 +1261,43 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 { struct wined3d_cs_set_shader_resource_view *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; op->type = type; op->view_idx = view_idx; op->view = view; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_unordered_access_view *op = data; + struct wined3d_unordered_access_view *prev; + + prev = cs->state.unordered_access_view[op->pipeline][op->view_idx]; + cs->state.unordered_access_view[op->pipeline][op->view_idx] = op->view; + + if (op->view) + InterlockedIncrement(&op->view->resource->bind_count); + if (prev) + InterlockedDecrement(&prev->resource->bind_count); + + device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline)); +} + +void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline, + unsigned int view_idx, struct wined3d_unordered_access_view *view) +{ + struct wined3d_cs_set_unordered_access_view *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW; + op->pipeline = pipeline; + op->view_idx = view_idx; + op->view = view; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) @@ -3340,7 +1305,10 @@ static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) const struct wined3d_cs_set_sampler *op = data; cs->state.sampler[op->type][op->sampler_idx] = op->sampler; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); + if (op->type != WINED3D_SHADER_TYPE_COMPUTE) + device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + else + device_invalidate_state(cs->device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); } void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, @@ -3348,13 +1316,13 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type { struct wined3d_cs_set_sampler *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SAMPLER; op->type = type; op->sampler_idx = sampler_idx; op->sampler = sampler; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) @@ -3363,19 +1331,42 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) cs->state.shader[op->type] = op->shader; device_invalidate_state(cs->device, STATE_SHADER(op->type)); - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); + if (op->type != WINED3D_SHADER_TYPE_COMPUTE) + device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + else + device_invalidate_state(cs->device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); } void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) { struct wined3d_cs_set_shader *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SHADER; op->type = type; op->shader = shader; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_rasterizer_state *op = data; + + cs->state.rasterizer_state = op->state; + device_invalidate_state(cs->device, STATE_FRONTFACE); +} + +void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, + struct wined3d_rasterizer_state *rasterizer_state) +{ + struct wined3d_cs_set_rasterizer_state *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_RASTERIZER_STATE; + op->state = rasterizer_state; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) @@ -3390,12 +1381,12 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render { struct wined3d_cs_set_render_state *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; op->state = state; op->value = value; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) @@ -3411,13 +1402,13 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, { struct wined3d_cs_set_texture_state *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; op->stage = stage; op->state = state; op->value = value; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) @@ -3433,20 +1424,20 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, { struct wined3d_cs_set_sampler_state *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; op->sampler_idx = sampler_idx; op->state = state; op->value = value; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_transform *op = data; - cs->state.transforms[op->state] = *op->matrix; + cs->state.transforms[op->state] = op->matrix; if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); } @@ -3456,19 +1447,19 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform { struct wined3d_cs_set_transform *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_TRANSFORM; op->state = state; - op->matrix = matrix; + op->matrix = *matrix; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_clip_plane *op = data; - cs->state.clip_planes[op->plane_idx] = *op->plane; + cs->state.clip_planes[op->plane_idx] = op->plane; device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); } @@ -3476,12 +1467,12 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const { struct wined3d_cs_set_clip_plane *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; op->plane_idx = plane_idx; - op->plane = plane; + op->plane = *plane; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) @@ -3552,7 +1543,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture { struct wined3d_cs_set_color_key *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_COLOR_KEY; op->texture = texture; op->flags = flags; @@ -3564,14 +1555,14 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture else op->set = 0; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_material *op = data; - cs->state.material = *op->material; + cs->state.material = op->material; device_invalidate_state(cs->device, STATE_MATERIAL); } @@ -3579,337 +1570,1030 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma { struct wined3d_cs_set_material *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_MATERIAL; - op->material = material; + op->material = *material; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_light *op = data; + struct wined3d_light_info *light_info; + unsigned int light_idx, hash_idx; + + light_idx = op->light.OriginalIndex; + + if (!(light_info = wined3d_state_get_light(&cs->state, light_idx))) + { + TRACE("Adding new light.\n"); + if (!(light_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*light_info)))) + { + ERR("Failed to allocate light info.\n"); + return; + } + + hash_idx = LIGHTMAP_HASHFUNC(light_idx); + list_add_head(&cs->state.light_map[hash_idx], &light_info->entry); + light_info->glIndex = -1; + light_info->OriginalIndex = light_idx; + } + + if (light_info->glIndex != -1) + { + if (light_info->OriginalParms.type != op->light.OriginalParms.type) + device_invalidate_state(cs->device, STATE_LIGHT_TYPE); + device_invalidate_state(cs->device, STATE_ACTIVELIGHT(light_info->glIndex)); + } + + light_info->OriginalParms = op->light.OriginalParms; + light_info->position = op->light.position; + light_info->direction = op->light.direction; + light_info->exponent = op->light.exponent; + light_info->cutoff = op->light.cutoff; +} + +void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) +{ + struct wined3d_cs_set_light *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_LIGHT; + op->light = *light; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_light_enable *op = data; + struct wined3d_device *device = cs->device; + struct wined3d_light_info *light_info; + int prev_idx; + + if (!(light_info = wined3d_state_get_light(&cs->state, op->idx))) + { + ERR("Light doesn't exist.\n"); + return; + } + + prev_idx = light_info->glIndex; + wined3d_state_enable_light(&cs->state, &device->adapter->d3d_info, light_info, op->enable); + if (light_info->glIndex != prev_idx) + { + device_invalidate_state(device, STATE_LIGHT_TYPE); + device_invalidate_state(device, STATE_ACTIVELIGHT(op->enable ? light_info->glIndex : prev_idx)); + } +} + +void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, unsigned int idx, BOOL enable) +{ + struct wined3d_cs_set_light_enable *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_LIGHT_ENABLE; + op->idx = idx; + op->enable = enable; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static const struct +{ + size_t offset; + size_t size; + DWORD mask; +} +wined3d_cs_push_constant_info[] = +{ + /* WINED3D_PUSH_CONSTANTS_VS_F */ + {FIELD_OFFSET(struct wined3d_state, vs_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_VS_F}, + /* WINED3D_PUSH_CONSTANTS_PS_F */ + {FIELD_OFFSET(struct wined3d_state, ps_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_PS_F}, + /* WINED3D_PUSH_CONSTANTS_VS_I */ + {FIELD_OFFSET(struct wined3d_state, vs_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_VS_I}, + /* WINED3D_PUSH_CONSTANTS_PS_I */ + {FIELD_OFFSET(struct wined3d_state, ps_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_PS_I}, + /* WINED3D_PUSH_CONSTANTS_VS_B */ + {FIELD_OFFSET(struct wined3d_state, vs_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_VS_B}, + /* WINED3D_PUSH_CONSTANTS_PS_B */ + {FIELD_OFFSET(struct wined3d_state, ps_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_PS_B}, +}; + +static void wined3d_cs_st_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p, + unsigned int start_idx, unsigned int count, const void *constants) +{ + struct wined3d_device *device = cs->device; + unsigned int context_count; + unsigned int i; + size_t offset; + + if (p == WINED3D_PUSH_CONSTANTS_VS_F) + device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count); + else if (p == WINED3D_PUSH_CONSTANTS_PS_F) + device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count); + + offset = wined3d_cs_push_constant_info[p].offset + start_idx * wined3d_cs_push_constant_info[p].size; + memcpy((BYTE *)&cs->state + offset, constants, count * wined3d_cs_push_constant_info[p].size); + for (i = 0, context_count = device->context_count; i < context_count; ++i) + { + device->contexts[i]->constant_update_mask |= wined3d_cs_push_constant_info[p].mask; + } +} + +static void wined3d_cs_exec_push_constants(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_push_constants *op = data; + + wined3d_cs_st_push_constants(cs, op->type, op->start_idx, op->count, op->constants); +} + +static void wined3d_cs_mt_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p, + unsigned int start_idx, unsigned int count, const void *constants) +{ + struct wined3d_cs_push_constants *op; + size_t size; + + size = count * wined3d_cs_push_constant_info[p].size; + op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_push_constants, constants[size]), + WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_PUSH_CONSTANTS; + op->type = p; + op->start_idx = start_idx; + op->count = count; + memcpy(op->constants, constants, size); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) { struct wined3d_adapter *adapter = cs->device->adapter; - HRESULT hr; state_cleanup(&cs->state); memset(&cs->state, 0, sizeof(cs->state)); - if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize CS state, hr %#x.\n", hr); + state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); } void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) { struct wined3d_cs_reset_state *op; - op = cs->ops->require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_RESET_STATE; - cs->ops->submit(cs); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = +static void wined3d_cs_exec_callback(struct wined3d_cs *cs, const void *data) { + const struct wined3d_cs_callback *op = data; + + op->callback(op->object); +} + +static void wined3d_cs_emit_callback(struct wined3d_cs *cs, void (*callback)(void *object), void *object) +{ + struct wined3d_cs_callback *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_CALLBACK; + op->callback = callback; + op->object = object; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +void wined3d_cs_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) +{ + wined3d_cs_emit_callback(cs, callback, object); +} + +void wined3d_cs_init_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) +{ + wined3d_cs_emit_callback(cs, callback, object); +} + +static void wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_query_issue *op = data; + struct wined3d_query *query = op->query; + BOOL poll; + + poll = query->query_ops->query_issue(query, op->flags); + + if (!cs->thread) + return; + + if (poll && list_empty(&query->poll_list_entry)) + { + list_add_tail(&cs->query_poll_list, &query->poll_list_entry); + return; + } + + /* This can happen if occlusion queries are restarted. This discards the + * old result, since polling it could result in a GL error. */ + if ((op->flags & WINED3DISSUE_BEGIN) && !poll && !list_empty(&query->poll_list_entry)) + { + list_remove(&query->poll_list_entry); + list_init(&query->poll_list_entry); + InterlockedIncrement(&query->counter_retrieved); + return; + } + + /* This can happen when an occlusion query is ended without being started, + * in which case we don't want to poll, but still have to counter-balance + * the increment of the main counter. + * + * This can also happen if an event query is re-issued before the first + * fence was reached. In this case the query is already in the list and + * the poll function will check the new fence. We have to counter-balance + * the discarded increment. */ + if (op->flags & WINED3DISSUE_END) + InterlockedIncrement(&query->counter_retrieved); +} + +void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) +{ + struct wined3d_cs_query_issue *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_QUERY_ISSUE; + op->query = query; + op->flags = flags; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_preload_resource(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_preload_resource *op = data; + struct wined3d_resource *resource = op->resource; + + resource->resource_ops->resource_preload(resource); + wined3d_resource_release(resource); +} + +void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) +{ + struct wined3d_cs_preload_resource *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_PRELOAD_RESOURCE; + op->resource = resource; + + wined3d_resource_acquire(resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_unload_resource(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_unload_resource *op = data; + struct wined3d_resource *resource = op->resource; + + resource->resource_ops->resource_unload(resource); + wined3d_resource_release(resource); +} + +void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) +{ + struct wined3d_cs_unload_resource *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_UNLOAD_RESOURCE; + op->resource = resource; + + wined3d_resource_acquire(resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_map(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_map *op = data; + struct wined3d_resource *resource = op->resource; + + *op->hr = resource->resource_ops->resource_sub_resource_map(resource, + op->sub_resource_idx, op->map_desc, op->box, op->flags); +} + +HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags) +{ + struct wined3d_cs_map *op; + HRESULT hr; + + /* Mapping resources from the worker thread isn't an issue by itself, but + * increasing the map count would be visible to applications. */ + wined3d_not_from_cs(cs); + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op->opcode = WINED3D_CS_OP_MAP; + op->resource = resource; + op->sub_resource_idx = sub_resource_idx; + op->map_desc = map_desc; + op->box = box; + op->flags = flags; + op->hr = &hr; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); + cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); + + return hr; +} + +static void wined3d_cs_exec_unmap(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_unmap *op = data; + struct wined3d_resource *resource = op->resource; + + *op->hr = resource->resource_ops->resource_sub_resource_unmap(resource, op->sub_resource_idx); +} + +HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx) +{ + struct wined3d_cs_unmap *op; + HRESULT hr; + + wined3d_not_from_cs(cs); + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op->opcode = WINED3D_CS_OP_UNMAP; + op->resource = resource; + op->sub_resource_idx = sub_resource_idx; + op->hr = &hr; + + cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); + cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); + + return hr; +} + +static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_blt_sub_resource *op = data; + + if (op->dst_resource->type == WINED3D_RTYPE_BUFFER) + { + if (FAILED(wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left, + buffer_from_resource(op->src_resource), op->src_box.left, + op->src_box.right - op->src_box.left))) + ERR("Failed to copy buffer.\n"); + } + else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_surface *dst_surface, *src_surface; + struct wined3d_texture *dst_texture, *src_texture; + RECT dst_rect, src_rect; + + dst_texture = texture_from_resource(op->dst_resource); + src_texture = texture_from_resource(op->src_resource); + dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface; + src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface; + SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom); + SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom); + + if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface, + &src_rect, op->flags, &op->fx, op->filter))) + FIXME("Blit failed.\n"); + } + else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D) + { + struct wined3d_texture *src_texture, *dst_texture; + unsigned int level, update_w, update_h, update_d; + unsigned int row_pitch, slice_pitch; + struct wined3d_context *context; + struct wined3d_bo_address addr; + + if (op->flags) + { + FIXME("Flags %#x not implemented for %s resources.\n", + op->flags, debug_d3dresourcetype(op->dst_resource->type)); + goto error; + } + + if (op->src_resource->format != op->dst_resource->format) + { + FIXME("Format conversion not implemented for %s resources.\n", + debug_d3dresourcetype(op->dst_resource->type)); + goto error; + } + + update_w = op->dst_box.right - op->dst_box.left; + update_h = op->dst_box.bottom - op->dst_box.top; + update_d = op->dst_box.back - op->dst_box.front; + if (op->src_box.right - op->src_box.left != update_w + || op->src_box.bottom - op->src_box.top != update_h + || op->src_box.back - op->src_box.front != update_d) + { + FIXME("Stretching not implemented for %s resources.\n", + debug_d3dresourcetype(op->dst_resource->type)); + goto error; + } + + if (op->src_box.left || op->src_box.top || op->src_box.front) + { + FIXME("Source box %s not supported for %s resources.\n", + debug_box(&op->src_box), debug_d3dresourcetype(op->dst_resource->type)); + goto error; + } + + dst_texture = texture_from_resource(op->dst_resource); + src_texture = texture_from_resource(op->src_resource); + + context = context_acquire(cs->device, NULL, 0); + + if (!wined3d_texture_load_location(src_texture, op->src_sub_resource_idx, + context, src_texture->resource.map_binding)) + { + ERR("Failed to load source sub-resource into %s.\n", + wined3d_debug_location(src_texture->resource.map_binding)); + context_release(context); + goto error; + } + + level = op->dst_sub_resource_idx % dst_texture->level_count; + if (update_w == wined3d_texture_get_level_width(dst_texture, level) + && update_h == wined3d_texture_get_level_height(dst_texture, level) + && update_d == wined3d_texture_get_level_depth(dst_texture, level)) + { + wined3d_texture_prepare_texture(dst_texture, context, FALSE); + } + else if (!wined3d_texture_load_location(dst_texture, op->dst_sub_resource_idx, + context, WINED3D_LOCATION_TEXTURE_RGB)) + { + ERR("Failed to load destination sub-resource.\n"); + context_release(context); + goto error; + } + + wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, src_texture->resource.map_binding); + wined3d_texture_get_pitch(src_texture, op->src_sub_resource_idx % src_texture->level_count, + &row_pitch, &slice_pitch); + + wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); + wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, &op->dst_box, + wined3d_const_bo_address(&addr), row_pitch, slice_pitch); + wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); + + context_release(context); + } + else + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type)); + } + +error: + if (op->src_resource) + wined3d_resource_release(op->src_resource); + wined3d_resource_release(op->dst_resource); +} + +void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource, + unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource, + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +{ + struct wined3d_cs_blt_sub_resource *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_BLT_SUB_RESOURCE; + op->dst_resource = dst_resource; + op->dst_sub_resource_idx = dst_sub_resource_idx; + op->dst_box = *dst_box; + op->src_resource = src_resource; + op->src_sub_resource_idx = src_sub_resource_idx; + op->src_box = *src_box; + op->flags = flags; + if (fx) + op->fx = *fx; + op->filter = filter; + + wined3d_resource_acquire(dst_resource); + if (src_resource) + wined3d_resource_acquire(src_resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + if (flags & WINED3D_BLT_SYNCHRONOUS) + cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_update_sub_resource *op = data; + const struct wined3d_box *box = &op->box; + unsigned int width, height, depth, level; + struct wined3d_const_bo_address addr; + struct wined3d_context *context; + struct wined3d_texture *texture; + + if (op->resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_buffer *buffer = buffer_from_resource(op->resource); + HRESULT hr; + + if (FAILED(hr = wined3d_buffer_upload_data(buffer, box, op->data.data))) + WARN("Failed to update buffer data, hr %#x.\n", hr); + + goto done; + } + + texture = wined3d_texture_from_resource(op->resource); + + level = op->sub_resource_idx % texture->level_count; + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + depth = wined3d_texture_get_level_depth(texture, level); + + addr.buffer_object = 0; + addr.addr = op->data.data; + + context = context_acquire(op->resource->device, NULL, 0); + + /* Only load the sub-resource for partial updates. */ + if (!box->left && !box->top && !box->front + && box->right == width && box->bottom == height && box->back == depth) + wined3d_texture_prepare_texture(texture, context, FALSE); + else + wined3d_texture_load_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + + wined3d_texture_upload_data(texture, op->sub_resource_idx, context, + box, &addr, op->data.row_pitch, op->data.slice_pitch); + + context_release(context); + + wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); + +done: + wined3d_resource_release(op->resource); +} + +void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, + unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, + unsigned int slice_pitch) +{ + struct wined3d_cs_update_sub_resource *op; +#if !defined(STAGING_CSMT) + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); +#else /* STAGING_CSMT */ + size_t data_size, size; + + if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS) + goto no_async; + + data_size = 0; + switch (resource->type) + { + case WINED3D_RTYPE_TEXTURE_3D: + data_size += (box->back - box->front - 1) * slice_pitch; + /* fall-through */ + case WINED3D_RTYPE_TEXTURE_2D: + data_size += (box->bottom - box->top - 1) * row_pitch; + /* fall-through */ + case WINED3D_RTYPE_TEXTURE_1D: + data_size += (box->right - box->left) * resource->format->byte_count; + break; + case WINED3D_RTYPE_BUFFER: + data_size = box->right - box->left; + break; + } + + size = FIELD_OFFSET(struct wined3d_cs_update_sub_resource, copy_data[data_size]); + if (!cs->ops->check_space(cs, size, WINED3D_CS_QUEUE_DEFAULT)) + goto no_async; + + op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT); +#endif /* STAGING_CSMT */ + op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; + op->resource = resource; + op->sub_resource_idx = sub_resource_idx; + op->box = *box; + op->data.row_pitch = row_pitch; + op->data.slice_pitch = slice_pitch; +#if !defined(STAGING_CSMT) + op->data.data = data; +#else /* STAGING_CSMT */ + op->data.data = op->copy_data; + memcpy(op->copy_data, data, data_size); #endif /* STAGING_CSMT */ - /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, - /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, - /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, - /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, - /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, - /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, - /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, - /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, - /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, - /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, - /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, - /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, - /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, - /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, - /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, - /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, - /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, - /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, - /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, - /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, - /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, - /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, - /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, - /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, - /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, - /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, -#if defined(STAGING_CSMT) - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, - /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, - /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, - /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, - /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, - /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, - /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, - /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, - /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, - /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, - /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, - /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, - /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, - /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, - /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, - /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, - /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, - /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, - /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, - /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, - /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, - /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, - /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, - /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, - /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, - /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, - /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, - /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, - /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, - /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, -}; -static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) + wined3d_resource_acquire(resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +#if !defined(STAGING_CSMT) + /* The data pointer may go away, so we need to wait until it is read. + * Copying the data may be faster if it's small. */ + cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT); +#else /* STAGING_CSMT */ + return; + +no_async: + wined3d_resource_wait_idle(resource); + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); + op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; + op->resource = resource; + op->sub_resource_idx = sub_resource_idx; + op->box = *box; + op->data.row_pitch = row_pitch; + op->data.slice_pitch = slice_pitch; + op->data.data = data; + + wined3d_resource_acquire(resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); + cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); +#endif /* STAGING_CSMT */ +} + +static void wined3d_cs_exec_add_dirty_texture_region(struct wined3d_cs *cs, const void *data) { - struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; - size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); + const struct wined3d_cs_add_dirty_texture_region *op = data; + struct wined3d_texture *texture = op->texture; + unsigned int sub_resource_idx, i; + struct wined3d_context *context; - if (queue_size - size < queue->head) + context = context_acquire(cs->device, NULL, 0); + sub_resource_idx = op->layer * texture->level_count; + for (i = 0; i < texture->level_count; ++i, ++sub_resource_idx) { - struct wined3d_cs_skip *skip; - size_t nop_size = queue_size - queue->head; - - skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); - if (nop_size < sizeof(*skip)) - { - skip->opcode = WINED3D_CS_OP_NOP; - } + if (wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding)) + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); else - { - skip->opcode = WINED3D_CS_OP_SKIP; - skip->size = nop_size; - } - - if (prio) - cs->ops->submit_prio(cs, nop_size); - else - cs->ops->submit(cs, nop_size); - - assert(!queue->head); + ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding)); } + context_release(context); - while(1) - { - LONG head = queue->head; - LONG tail = *((volatile LONG *)&queue->tail); - LONG new_pos; - /* Empty */ - if (head == tail) - break; - /* Head ahead of tail, take care of wrap-around */ - new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); - if (head > tail && (new_pos || tail)) - break; - /* Tail ahead of head, but still enough space */ - if (new_pos < tail && new_pos) - break; - - TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, - (unsigned int) size); - } - - return &queue->data[queue->head]; + wined3d_resource_release(&texture->resource); } -static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) +void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, + struct wined3d_texture *texture, unsigned int layer) { - return _wined3d_cs_mt_require_space(cs, size, FALSE); + struct wined3d_cs_add_dirty_texture_region *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION; + op->texture = texture; + op->layer = layer; + + wined3d_resource_acquire(&texture->resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) +static void wined3d_cs_exec_clear_unordered_access_view(struct wined3d_cs *cs, const void *data) { - return _wined3d_cs_mt_require_space(cs, size, TRUE); + const struct wined3d_cs_clear_unordered_access_view *op = data; + struct wined3d_unordered_access_view *view = op->view; + struct wined3d_context *context; + + context = context_acquire(cs->device, NULL, 0); + wined3d_unordered_access_view_clear_uint(view, &op->clear_value, context); + context_release(context); + + wined3d_resource_release(view->resource); +} + +void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) +{ + struct wined3d_cs_clear_unordered_access_view *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW; + op->view = view; + op->clear_value = *clear_value; + + wined3d_resource_acquire(view->resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } -/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an - * OP itself. */ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) { struct wined3d_cs_stop *op; - op = wined3d_cs_mt_require_space(cs, sizeof(*op)); + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_STOP; - wined3d_cs_mt_submit(cs, sizeof(*op)); + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); + cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT); } -static void wined3d_cs_mt_finish(struct wined3d_cs *cs) +static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = { - BOOL fence; - - if (cs->thread_id == GetCurrentThreadId()) - { - static BOOL once; - if (!once) - { - FIXME("flush_and_wait called from cs thread\n"); - once = TRUE; - } - return; - } - - wined3d_cs_emit_fence(cs, &fence); - - /* A busy wait should be fine, we're not supposed to have to wait very - * long. */ - while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -} - -static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) -{ - BOOL fence; - - if (cs->thread_id == GetCurrentThreadId()) - { - static BOOL once; - if (!once) - { - FIXME("flush_and_wait called from cs thread\n"); - once = TRUE; - } - return; - } - - wined3d_cs_emit_fence_prio(cs, &fence); - - /* A busy wait should be fine, we're not supposed to have to wait very - * long. */ - while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -} - -static const struct wined3d_cs_ops wined3d_cs_mt_ops = -{ - wined3d_cs_mt_require_space, - wined3d_cs_mt_require_space_prio, - wined3d_cs_mt_submit, - wined3d_cs_mt_submit_prio, - wined3d_cs_mt_finish, - wined3d_cs_mt_finish_prio, + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, + /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, + /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, + /* WINED3D_CS_OP_DISPATCH */ wined3d_cs_exec_dispatch, + /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, + /* WINED3D_CS_OP_FLUSH */ wined3d_cs_exec_flush, + /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, + /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, + /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, + /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, + /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, + /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, + /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, + /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, + /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, + /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, + /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, + /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, + /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, + /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, + /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, + /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state, + /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, + /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, + /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, + /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, + /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, + /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, + /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, + /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + /* WINED3D_CS_OP_PUSH_CONSTANTS */ wined3d_cs_exec_push_constants, + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, + /* WINED3D_CS_OP_CALLBACK */ wined3d_cs_exec_callback, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource, + /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource, + /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map, + /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap, + /* WINED3D_CS_OP_BLT_SUB_RESOURCE */ wined3d_cs_exec_blt_sub_resource, + /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, + /* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION */ wined3d_cs_exec_add_dirty_texture_region, + /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view, }; -static void wined3d_cs_st_submit(struct wined3d_cs *cs, size_t size) +#if defined(STAGING_CSMT) +static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { - enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&cs->queue.data; + return TRUE; +} - if (opcode >= WINED3D_CS_OP_STOP) +#endif /* STAGING_CSMT */ +static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) +{ + if (size > (cs->data_size - cs->end)) { - ERR("Invalid opcode %#x.\n", opcode); - return; + size_t new_size; + void *new_data; + + new_size = max(size, cs->data_size * 2); + if (!cs->end) + new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, new_size); + else + new_data = HeapAlloc(GetProcessHeap(), 0, new_size); + if (!new_data) + return NULL; + + cs->data_size = new_size; + cs->start = cs->end = 0; + cs->data = new_data; } - wined3d_cs_op_handlers[opcode](cs, &cs->queue.data); + cs->end += size; + + return (BYTE *)cs->data + cs->start; } -static void wined3d_cs_st_finish(struct wined3d_cs *cs) +static void wined3d_cs_st_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) { + enum wined3d_cs_op opcode; + size_t start; + BYTE *data; + + data = cs->data; + start = cs->start; + cs->start = cs->end; + + opcode = *(const enum wined3d_cs_op *)&data[start]; + if (opcode >= WINED3D_CS_OP_STOP) + ERR("Invalid opcode %#x.\n", opcode); + else + wined3d_cs_op_handlers[opcode](cs, &data[start]); + + if (cs->data == data) + cs->start = cs->end = start; + else if (!start) + HeapFree(GetProcessHeap(), 0, data); } -static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) { - return cs->queue.data; } static const struct wined3d_cs_ops wined3d_cs_st_ops = { - wined3d_cs_st_require_space, +#if defined(STAGING_CSMT) + wined3d_cs_st_check_space, +#endif /* STAGING_CSMT */ wined3d_cs_st_require_space, wined3d_cs_st_submit, - wined3d_cs_st_submit, - wined3d_cs_st_finish, wined3d_cs_st_finish, + wined3d_cs_st_push_constants, }; -void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, - struct wined3d_context *context, struct wined3d_surface *depth_stencil) +static BOOL wined3d_cs_queue_is_empty(const struct wined3d_cs_queue *queue) { - if (cs->onscreen_depth_stencil) - { - surface_load_ds_location(cs->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); - - surface_modify_ds_location(cs->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, - cs->onscreen_depth_stencil->ds_current_size.cx, - cs->onscreen_depth_stencil->ds_current_size.cy); - wined3d_texture_decref(cs->onscreen_depth_stencil->container); - } - cs->onscreen_depth_stencil = depth_stencil; - wined3d_texture_incref(cs->onscreen_depth_stencil->container); + return *(volatile LONG *)&queue->head == queue->tail; } -static inline void poll_queries(struct wined3d_cs *cs) +static void wined3d_cs_queue_submit(struct wined3d_cs_queue *queue, struct wined3d_cs *cs) +{ + struct wined3d_cs_packet *packet; + size_t packet_size; + + packet = (struct wined3d_cs_packet *)&queue->data[queue->head]; + packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[packet->size]); + InterlockedExchange(&queue->head, (queue->head + packet_size) & (WINED3D_CS_QUEUE_SIZE - 1)); + + if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) + SetEvent(cs->event); +} + +static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) +{ + if (cs->thread_id == GetCurrentThreadId()) + { + wined3d_cs_st_submit(cs, queue_id); + return; + } + + wined3d_cs_queue_submit(&cs->queue[queue_id], cs); +} + +#if defined(STAGING_CSMT) +static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size) +{ + size_t queue_size = ARRAY_SIZE(queue->data); + size_t header_size, packet_size, remaining; + + header_size = FIELD_OFFSET(struct wined3d_cs_packet, data[0]); + size = (size + header_size - 1) & ~(header_size - 1); + packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[size]); + + remaining = queue_size - queue->head; + return (remaining >= packet_size); +} + +#endif /* STAGING_CSMT */ +static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs) +{ + size_t queue_size = ARRAY_SIZE(queue->data); + size_t header_size, packet_size, remaining; + struct wined3d_cs_packet *packet; + + header_size = FIELD_OFFSET(struct wined3d_cs_packet, data[0]); + size = (size + header_size - 1) & ~(header_size - 1); + packet_size = FIELD_OFFSET(struct wined3d_cs_packet, data[size]); + if (packet_size >= WINED3D_CS_QUEUE_SIZE) + { + ERR("Packet size %lu >= queue size %u.\n", + (unsigned long)packet_size, WINED3D_CS_QUEUE_SIZE); + return NULL; + } + + remaining = queue_size - queue->head; + if (remaining < packet_size) + { + size_t nop_size = remaining - header_size; + struct wined3d_cs_nop *nop; + + TRACE("Inserting a nop for %lu + %lu bytes.\n", + (unsigned long)header_size, (unsigned long)nop_size); + + nop = wined3d_cs_queue_require_space(queue, nop_size, cs); + if (nop_size) + nop->opcode = WINED3D_CS_OP_NOP; + + wined3d_cs_queue_submit(queue, cs); + assert(!queue->head); + } + + for (;;) + { + LONG tail = *(volatile LONG *)&queue->tail; + LONG head = queue->head; + LONG new_pos; + + /* Empty. */ + if (head == tail) + break; + new_pos = (head + packet_size) & (WINED3D_CS_QUEUE_SIZE - 1); + /* Head ahead of tail. We checked the remaining size above, so we only + * need to make sure we don't make head equal to tail. */ + if (head > tail && (new_pos != tail)) + break; + /* Tail ahead of head. Make sure the new head is before the tail as + * well. Note that new_pos is 0 when it's at the end of the queue. */ + if (new_pos < tail && new_pos) + break; + + TRACE("Waiting for free space. Head %u, tail %u, packet size %lu.\n", + head, tail, (unsigned long)packet_size); + } + + packet = (struct wined3d_cs_packet *)&queue->data[queue->head]; + packet->size = size; + return packet->data; +} + +#if defined(STAGING_CSMT) +static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) +{ + if (cs->thread_id == GetCurrentThreadId()) + return wined3d_cs_st_check_space(cs, size, queue_id); + + return wined3d_cs_queue_check_space(&cs->queue[queue_id], size); +} + +#endif /* STAGING_CSMT */ +static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) +{ + if (cs->thread_id == GetCurrentThreadId()) + return wined3d_cs_st_require_space(cs, size, queue_id); + + return wined3d_cs_queue_require_space(&cs->queue[queue_id], size, cs); +} + +static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id) +{ + if (cs->thread_id == GetCurrentThreadId()) + { + wined3d_cs_st_finish(cs, queue_id); + return; + } + + while (!wined3d_cs_queue_is_empty(&cs->queue[queue_id])) + wined3d_pause(); +} + +static const struct wined3d_cs_ops wined3d_cs_mt_ops = +{ +#if defined(STAGING_CSMT) + wined3d_cs_mt_check_space, +#endif /* STAGING_CSMT */ + wined3d_cs_mt_require_space, + wined3d_cs_mt_submit, + wined3d_cs_mt_finish, + wined3d_cs_mt_push_constants, +}; + +static void poll_queries(struct wined3d_cs *cs) { struct wined3d_query *query, *cursor; LIST_FOR_EACH_ENTRY_SAFE(query, cursor, &cs->query_poll_list, struct wined3d_query, poll_list_entry) { - BOOL ret; + if (!query->query_ops->query_poll(query, 0)) + continue; - ret = query->query_ops->query_poll(query); - if (ret) - { - list_remove(&query->poll_list_entry); - list_init(&query->poll_list_entry); - InterlockedIncrement(&query->counter_retrieved); - } + list_remove(&query->poll_list_entry); + list_init(&query->poll_list_entry); + InterlockedIncrement(&query->counter_retrieved); } } -static inline BOOL queue_is_empty(const struct wined3d_cs_queue *queue) -{ - return *((volatile LONG *)&queue->head) == queue->tail; -} - static void wined3d_cs_wait_event(struct wined3d_cs *cs) { InterlockedExchange(&cs->waiting_for_event, TRUE); - /* The main thread might enqueue a finish command and block on it - * after the worker thread decided to enter wined3d_cs_wait_event - * and before waiting_for_event was set to TRUE. Check again if - * the queues are empty */ - if (!queue_is_empty(&cs->prio_queue) || !queue_is_empty(&cs->queue)) - { - /* The main thread might have signalled the event, or be in the process - * of doing so. Wait for the event to reset it. ResetEvent is not good - * because the main thread might be beween the waiting_for_event reset - * and SignalEvent call. */ - if (!InterlockedCompareExchange(&cs->waiting_for_event, FALSE, FALSE)) - WaitForSingleObject(cs->event, INFINITE); - } - else - { - WaitForSingleObject(cs->event, INFINITE); - } + /* The main thread might have enqueued a command and blocked on it after + * the CS thread decided to enter wined3d_cs_wait_event(), but before + * "waiting_for_event" was set. + * + * Likewise, we can race with the main thread when resetting + * "waiting_for_event", in which case we would need to call + * WaitForSingleObject() because the main thread called SetEvent(). */ + if (!(wined3d_cs_queue_is_empty(&cs->queue[WINED3D_CS_QUEUE_DEFAULT]) + && wined3d_cs_queue_is_empty(&cs->queue[WINED3D_CS_QUEUE_MAP])) + && InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) + return; + + WaitForSingleObject(cs->event, INFINITE); } -static DWORD WINAPI wined3d_cs_run(void *thread_param) +static DWORD WINAPI wined3d_cs_run(void *ctx) { - struct wined3d_cs *cs = thread_param; - enum wined3d_cs_op opcode; - LONG tail; - char poll = 0; + struct wined3d_cs_packet *packet; struct wined3d_cs_queue *queue; unsigned int spin_count = 0; + struct wined3d_cs *cs = ctx; + enum wined3d_cs_op opcode; + unsigned int poll = 0; + LONG tail; TRACE("Started.\n"); @@ -3917,145 +2601,52 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) cs->thread_id = GetCurrentThreadId(); for (;;) { - if (poll == 10) + if (++poll == WINED3D_CS_QUERY_POLL_INTERVAL) { - poll = 0; poll_queries(cs); - } - else - poll++; - - if (!queue_is_empty(&cs->prio_queue)) - { - queue = &cs->prio_queue; - } - else if (!queue_is_empty(&cs->queue)) - { - queue = &cs->queue; - if (!queue_is_empty(&cs->prio_queue)) - queue = &cs->prio_queue; - } - else - { - spin_count++; - if (spin_count >= WINED3D_CS_SPIN_COUNT && list_empty(&cs->query_poll_list)) - wined3d_cs_wait_event(cs); - - continue; + poll = 0; } + queue = &cs->queue[WINED3D_CS_QUEUE_MAP]; + if (wined3d_cs_queue_is_empty(queue)) + { + queue = &cs->queue[WINED3D_CS_QUEUE_DEFAULT]; + if (wined3d_cs_queue_is_empty(queue)) + { + if (++spin_count >= WINED3D_CS_SPIN_COUNT && list_empty(&cs->query_poll_list)) + wined3d_cs_wait_event(cs); + continue; + } + } spin_count = 0; tail = queue->tail; - opcode = *(const enum wined3d_cs_op *)&queue->data[tail]; - - if (opcode >= WINED3D_CS_OP_STOP) + packet = (struct wined3d_cs_packet *)&queue->data[tail]; + if (packet->size) { - if (opcode > WINED3D_CS_OP_STOP) - ERR("Invalid opcode %#x.\n", opcode); - goto done; + opcode = *(const enum wined3d_cs_op *)packet->data; + + if (opcode >= WINED3D_CS_OP_STOP) + { + if (opcode > WINED3D_CS_OP_STOP) + ERR("Invalid opcode %#x.\n", opcode); + break; + } + + wined3d_cs_op_handlers[opcode](cs, packet->data); } - tail += wined3d_cs_op_handlers[opcode](cs, &queue->data[tail]); + tail += FIELD_OFFSET(struct wined3d_cs_packet, data[packet->size]); tail &= (WINED3D_CS_QUEUE_SIZE - 1); InterlockedExchange(&queue->tail, tail); } -done: + cs->queue[WINED3D_CS_QUEUE_MAP].tail = cs->queue[WINED3D_CS_QUEUE_MAP].head = 0; + cs->queue[WINED3D_CS_QUEUE_DEFAULT].tail = cs->queue[WINED3D_CS_QUEUE_DEFAULT].head = 0; TRACE("Stopped.\n"); - return 0; + FreeLibraryAndExitThread(cs->wined3d_module, 0); } -struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) -{ - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_cs *cs = NULL; - - if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) - return NULL; - - if (FAILED(state_init(&cs->state, gl_info, &device->adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - { - goto err; - } - - cs->ops = &wined3d_cs_st_ops; - cs->device = device; - - if (wined3d_settings.cs_multithreaded) - { - cs->ops = &wined3d_cs_mt_ops; - - cs->event = CreateEventW(NULL, FALSE, FALSE, NULL); - - if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) - { - ERR("Failed to create wined3d command stream thread.\n"); - goto err; - } - } - - return cs; - -err: - if (cs) - state_cleanup(&cs->state); - HeapFree(GetProcessHeap(), 0, cs); - return NULL; -} - -void wined3d_cs_destroy(struct wined3d_cs *cs) -{ - DWORD ret; - - state_cleanup(&cs->state); - - if (wined3d_settings.cs_multithreaded) - { - wined3d_cs_emit_stop(cs); - - ret = WaitForSingleObject(cs->thread, INFINITE); - CloseHandle(cs->thread); - if (ret != WAIT_OBJECT_0) - ERR("Wait failed (%#x).\n", ret); - if (!CloseHandle(cs->event)) - ERR("Closing event failed.\n"); - } - -#else /* STAGING_CSMT */ -}; - -static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -{ - if (size > cs->data_size) - { - void *new_data; - - size = max( size, cs->data_size * 2 ); - if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) - return NULL; - - cs->data_size = size; - cs->data = new_data; - } - - return cs->data; -} - -static void wined3d_cs_st_submit(struct wined3d_cs *cs) -{ - enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; - - wined3d_cs_op_handlers[opcode](cs, cs->data); -} - -static const struct wined3d_cs_ops wined3d_cs_st_ops = -{ - wined3d_cs_st_require_space, - wined3d_cs_st_submit, -}; - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; @@ -4064,39 +2655,74 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) return NULL; - if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) - { - HeapFree(GetProcessHeap(), 0, cs); - return NULL; - } - - if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - { - HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); - HeapFree(GetProcessHeap(), 0, cs); - return NULL; - } - cs->ops = &wined3d_cs_st_ops; cs->device = device; - cs->data_size = WINED3D_INITIAL_CS_SIZE; - if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) + if (!(cs->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*cs->fb.render_targets)))) { HeapFree(GetProcessHeap(), 0, cs); return NULL; } + state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT); + + cs->data_size = WINED3D_INITIAL_CS_SIZE; + if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) + goto fail; + + if (wined3d_settings.cs_multithreaded + && !RtlIsCriticalSectionLockedByThread(NtCurrentTeb()->Peb->LoaderLock)) + { + cs->ops = &wined3d_cs_mt_ops; + + if (!(cs->event = CreateEventW(NULL, FALSE, FALSE, NULL))) + { + ERR("Failed to create command stream event.\n"); + HeapFree(GetProcessHeap(), 0, cs->data); + goto fail; + } + + if (!(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (const WCHAR *)wined3d_cs_run, &cs->wined3d_module))) + { + ERR("Failed to get wined3d module handle.\n"); + CloseHandle(cs->event); + HeapFree(GetProcessHeap(), 0, cs->data); + goto fail; + } + + if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) + { + ERR("Failed to create wined3d command stream thread.\n"); + FreeLibrary(cs->wined3d_module); + CloseHandle(cs->event); + HeapFree(GetProcessHeap(), 0, cs->data); + goto fail; + } + } + return cs; + +fail: + state_cleanup(&cs->state); + HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs); + return NULL; } void wined3d_cs_destroy(struct wined3d_cs *cs) { + if (cs->thread) + { + wined3d_cs_emit_stop(cs); + CloseHandle(cs->thread); + if (!CloseHandle(cs->event)) + ERR("Closing event failed.\n"); + } + state_cleanup(&cs->state); HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); HeapFree(GetProcessHeap(), 0, cs->data); -#endif /* STAGING_CSMT */ HeapFree(GetProcessHeap(), 0, cs); } diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index f4db5933e4a..14d4422cc7c 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -27,6 +27,7 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(winediag); /* Define the default light parameters as specified by MSDN. */ const struct wined3d_light WINED3D_default_light = @@ -48,7 +49,7 @@ const struct wined3d_light WINED3D_default_light = * actually have the same values in GL and D3D. */ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) { - switch(primitive_type) + switch (primitive_type) { case WINED3D_PT_POINTLIST: return GL_POINTS; @@ -80,8 +81,11 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) case WINED3D_PT_TRIANGLESTRIP_ADJ: return GL_TRIANGLE_STRIP_ADJACENCY_ARB; + case WINED3D_PT_PATCH: + return GL_PATCHES; + default: - FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type)); + FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type)); case WINED3D_PT_UNDEFINED: return ~0u; } @@ -89,7 +93,7 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) { - switch(primitive_type) + switch (primitive_type) { case GL_POINTS: return WINED3D_PT_POINTLIST; @@ -121,8 +125,11 @@ static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_t case GL_TRIANGLE_STRIP_ADJACENCY_ARB: return WINED3D_PT_TRIANGLESTRIP_ADJ; + case GL_PATCHES: + return WINED3D_PT_PATCH; + default: - FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type)); + FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type)); case ~0u: return WINED3D_PT_UNDEFINED; } @@ -190,110 +197,32 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context device->contexts = new_array; } -#if !defined(STAGING_CSMT) -void device_switch_onscreen_ds(struct wined3d_device *device, - struct wined3d_context *context, struct wined3d_surface *depth_stencil) -{ - if (device->onscreen_depth_stencil) - { - surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); - - surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, - device->onscreen_depth_stencil->ds_current_size.cx, - device->onscreen_depth_stencil->ds_current_size.cy); - wined3d_texture_decref(device->onscreen_depth_stencil->container); - } - device->onscreen_depth_stencil = depth_stencil; - wined3d_texture_incref(device->onscreen_depth_stencil->container); -} - -#endif /* STAGING_CSMT */ static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect) { + unsigned int height = wined3d_texture_get_level_height(target->container, target->texture_level); + unsigned int width = wined3d_texture_get_level_width(target->container, target->texture_level); + /* partial draw rect */ - if (draw_rect->left || draw_rect->top - || draw_rect->right < target->resource.width - || draw_rect->bottom < target->resource.height) + if (draw_rect->left || draw_rect->top || draw_rect->right < width || draw_rect->bottom < height) return FALSE; /* partial clear rect */ if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0 - || clear_rect->right < target->resource.width - || clear_rect->bottom < target->resource.height)) + || clear_rect->right < width || clear_rect->bottom < height)) return FALSE; return TRUE; } -static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context *context, - DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect, RECT *out_rect) -{ - RECT current_rect, r; - -#if defined(STAGING_CSMT) - if (ds->resource.locations & WINED3D_LOCATION_DISCARDED) -#else /* STAGING_CSMT */ - if (ds->locations & WINED3D_LOCATION_DISCARDED) -#endif /* STAGING_CSMT */ - { - /* Depth buffer was discarded, make it entirely current in its new location since - * there is no other place where we would get data anyway. */ - SetRect(out_rect, 0, 0, ds->resource.width, ds->resource.height); - return; - } - -#if defined(STAGING_CSMT) - if (ds->resource.locations & location) -#else /* STAGING_CSMT */ - if (ds->locations & location) -#endif /* STAGING_CSMT */ - SetRect(¤t_rect, 0, 0, - ds->ds_current_size.cx, - ds->ds_current_size.cy); - else - SetRectEmpty(¤t_rect); - - IntersectRect(&r, draw_rect, ¤t_rect); - if (EqualRect(&r, draw_rect)) - { - /* current_rect ⊇ draw_rect, modify only. */ - SetRect(out_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); - return; - } - - if (EqualRect(&r, ¤t_rect)) - { - /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ - - if (!clear_rect) - { - /* Full clear, modify only. */ - *out_rect = *draw_rect; - return; - } - - IntersectRect(&r, draw_rect, clear_rect); - if (EqualRect(&r, draw_rect)) - { - /* clear_rect ⊇ draw_rect, modify only. */ - *out_rect = *draw_rect; - return; - } - } - - /* Full load. */ - surface_load_ds_location(ds, context, location); - SetRect(out_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); -} - void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb, - UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, + UINT rect_count, const RECT *clear_rect, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { - struct wined3d_surface *target = rt_count ? wined3d_rendertarget_view_get_surface(fb->render_targets[0]) : NULL; - struct wined3d_surface *depth_stencil = fb->depth_stencil - ? wined3d_rendertarget_view_get_surface(fb->depth_stencil) : NULL; - const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL; + struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL; + struct wined3d_surface *target = rtv ? wined3d_rendertarget_view_get_surface(rtv) : NULL; + struct wined3d_rendertarget_view *dsv = fb->depth_stencil; + struct wined3d_surface *depth_stencil = dsv ? wined3d_rendertarget_view_get_surface(dsv) : NULL; + const struct wined3d_state *state = &device->cs->state; const struct wined3d_gl_info *gl_info; UINT drawable_width, drawable_height; struct wined3d_color corrected_color; @@ -301,9 +230,11 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c GLbitfield clear_mask = 0; BOOL render_offscreen; unsigned int i; - RECT ds_rect; - context = context_acquire(device, target); + if (target) + context = context_acquire(device, target->container, rtv->sub_resource_idx); + else + context = context_acquire(device, NULL, 0); if (!context->valid) { context_release(context); @@ -322,51 +253,46 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c * checking all this if the dest surface is in the drawable anyway. */ for (i = 0; i < rt_count; ++i) { - struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]); - if (rt && rt->resource.format->id != WINED3DFMT_NULL) + struct wined3d_rendertarget_view *rtv = fb->render_targets[i]; + + if (rtv && rtv->format->id != WINED3DFMT_NULL) { - if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect)) -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&rt->resource, context, rt->container->resource.draw_binding); -#else /* STAGING_CSMT */ - surface_load_location(rt, context, rt->container->resource.draw_binding); -#endif /* STAGING_CSMT */ + struct wined3d_texture *rt = wined3d_texture_from_resource(rtv->resource); + + if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, rect_count ? clear_rect : NULL)) + wined3d_texture_load_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding); else - wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding); + wined3d_texture_prepare_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding); } } if (target) { render_offscreen = context->render_offscreen; - surface_get_drawable_size(target, context, &drawable_width, &drawable_height); + wined3d_rendertarget_view_get_drawable_size(rtv, context, &drawable_width, &drawable_height); } else { render_offscreen = TRUE; - drawable_width = depth_stencil->pow2Width; - drawable_height = depth_stencil->pow2Height; + drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, + depth_stencil->texture_level); + drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, + depth_stencil->texture_level); } if (depth_stencil && render_offscreen) - wined3d_surface_prepare(depth_stencil, context, depth_stencil->container->resource.draw_binding); + wined3d_texture_prepare_location(depth_stencil->container, + dsv->sub_resource_idx, context, dsv->resource->draw_binding); if (flags & WINED3DCLEAR_ZBUFFER) { - DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; + DWORD location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; -#if defined(STAGING_CSMT) - if (!render_offscreen && depth_stencil != device->cs->onscreen_depth_stencil) - wined3d_cs_switch_onscreen_ds(device->cs, context, depth_stencil); -#else /* STAGING_CSMT */ - if (!render_offscreen && depth_stencil != device->onscreen_depth_stencil) - device_switch_onscreen_ds(device, context, depth_stencil); -#endif /* STAGING_CSMT */ - prepare_ds_clear(depth_stencil, context, location, - draw_rect, rect_count, clear_rect, &ds_rect); + wined3d_texture_load_location(depth_stencil->container, + dsv->sub_resource_idx, context, location); } - if (!context_apply_clear_state(context, device, rt_count, fb)) + if (!context_apply_clear_state(context, state, rt_count, fb)) { context_release(context); WARN("Failed to apply clear state, skipping clear.\n"); @@ -390,9 +316,10 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (flags & WINED3DCLEAR_ZBUFFER) { - DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; + DWORD location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; - surface_modify_ds_location(depth_stencil, location, ds_rect.right, ds_rect.bottom); + wined3d_texture_validate_location(depth_stencil->container, dsv->sub_resource_idx, location); + wined3d_texture_invalidate_location(depth_stencil->container, dsv->sub_resource_idx, ~location); gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE)); @@ -405,21 +332,24 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c { for (i = 0; i < rt_count; ++i) { - struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]); + struct wined3d_rendertarget_view *rtv = fb->render_targets[i]; + struct wined3d_texture *texture; - if (rt) + if (!rtv) + continue; + + if (rtv->resource->type == WINED3D_RTYPE_BUFFER) { -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&rt->resource, rt->container->resource.draw_binding); - wined3d_resource_invalidate_location(&rt->resource, ~rt->container->resource.draw_binding); -#else /* STAGING_CSMT */ - surface_validate_location(rt, rt->container->resource.draw_binding); - surface_invalidate_location(rt, ~rt->container->resource.draw_binding); -#endif /* STAGING_CSMT */ + FIXME("Not supported on buffer resources.\n"); + continue; } + + texture = texture_from_resource(rtv->resource); + wined3d_texture_validate_location(texture, rtv->sub_resource_idx, rtv->resource->draw_binding); + wined3d_texture_invalidate_location(texture, rtv->sub_resource_idx, ~rtv->resource->draw_binding); } - if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, &device->state, fb)) + if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, fb)) { if (rt_count > 1) WARN("Clearing multiple sRGB render targets with no GL_ARB_framebuffer_sRGB " @@ -453,7 +383,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c clear_mask = clear_mask | GL_COLOR_BUFFER_BIT; } - if (!clear_rect) + if (!rect_count) { if (render_offscreen) { @@ -545,7 +475,7 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) wined3d_cs_destroy(device->cs); if (device->recording && wined3d_stateblock_decref(device->recording)) - FIXME("Something's still holding the recording stateblock.\n"); + ERR("Something's still holding the recording stateblock.\n"); device->recording = NULL; state_cleanup(&device->state); @@ -560,11 +490,11 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) { struct wined3d_resource *resource; - FIXME("Device released with resources still bound, acceptable but unexpected.\n"); + ERR("Device released with resources still bound.\n"); LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry) { - FIXME("Leftover resource %p with type %s (%#x).\n", + ERR("Leftover resource %p with type %s (%#x).\n", resource, debug_d3dresourcetype(resource->type), resource->type); } } @@ -616,23 +546,16 @@ static void device_load_logo(struct wined3d_device *device, const char *filename HRESULT hr; HDC dcb = NULL, dcs = NULL; - hbm = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); - if(hbm) + if (!(hbm = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION))) { - GetObjectA(hbm, sizeof(BITMAP), &bm); - dcb = CreateCompatibleDC(NULL); - if(!dcb) goto out; - SelectObject(dcb, hbm); - } - else - { - /* Create a 32x32 white surface to indicate that wined3d is used, but the specified image - * couldn't be loaded - */ - memset(&bm, 0, sizeof(bm)); - bm.bmWidth = 32; - bm.bmHeight = 32; + ERR_(winediag)("Failed to load logo %s.\n", wine_dbgstr_a(filename)); + return; } + GetObjectA(hbm, sizeof(BITMAP), &bm); + + if (!(dcb = CreateCompatibleDC(NULL))) + goto out; + SelectObject(dcb, hbm); desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = WINED3DFMT_B5G6R5_UNORM; @@ -644,34 +567,26 @@ static void device_load_logo(struct wined3d_device *device, const char *filename desc.height = bm.bmHeight; desc.depth = 1; desc.size = 0; - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, + WINED3D_TEXTURE_CREATE_MAPPABLE | WINED3D_TEXTURE_CREATE_GET_DC, NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture))) { ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr); goto out; } - if (dcb) + if (FAILED(hr = wined3d_texture_get_dc(device->logo_texture, 0, &dcs))) { - if (FAILED(hr = wined3d_texture_get_dc(device->logo_texture, 0, &dcs))) - goto out; - BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY); - wined3d_texture_release_dc(device->logo_texture, 0, dcs); - - color_key.color_space_low_value = 0; - color_key.color_space_high_value = 0; - wined3d_texture_set_color_key(device->logo_texture, WINED3D_CKEY_SRC_BLT, &color_key); + wined3d_texture_decref(device->logo_texture); + device->logo_texture = NULL; + goto out; } - else - { - const struct wined3d_color c = {1.0f, 1.0f, 1.0f, 1.0f}; - const RECT rect = {0, 0, desc.width, desc.height}; - struct wined3d_surface *surface; + BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY); + wined3d_texture_release_dc(device->logo_texture, 0, dcs); - /* Fill the surface with a white color to show that wined3d is there */ - surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0)); - surface_color_fill(surface, &rect, &c); - } + color_key.color_space_low_value = 0; + color_key.color_space_high_value = 0; + wined3d_texture_set_color_key(device->logo_texture, WINED3D_CKEY_SRC_BLT, &color_key); out: if (dcb) DeleteDC(dcb); @@ -679,159 +594,249 @@ out: } /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) -#else /* STAGING_CSMT */ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) -#endif /* STAGING_CSMT */ { + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int i, j, count; + unsigned int i; + DWORD color; + + if (d3d_info->wined3d_creation_flags & WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR) + color = 0x000000ff; + else + color = 0x00000000; + /* Under DirectX you can sample even if no texture is bound, whereas * OpenGL will only allow that when a valid texture is bound. * We emulate this by creating dummy textures and binding them * to each texture stage when the currently set D3D texture is NULL. */ + context_active_texture(context, gl_info, 0); - count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); - for (i = 0; i < count; ++i) + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_1d); + checkGLcall("glGenTextures"); + TRACE("Dummy 1D texture given name %u.\n", device->dummy_textures.tex_1d); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, device->dummy_textures.tex_1d); + checkGLcall("glBindTexture"); + + gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + checkGLcall("glTexImage1D"); + + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d); + checkGLcall("glGenTextures"); + TRACE("Dummy 2D texture given name %u.\n", device->dummy_textures.tex_2d); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); + checkGLcall("glBindTexture"); + + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + checkGLcall("glTexImage2D"); + + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) { - static const DWORD color = 0x000000ff; - - /* Make appropriate texture active */ - context_active_texture(context, gl_info, i); - - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_2d[i]); + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_rect); checkGLcall("glGenTextures"); - TRACE("Dummy 2D texture %u given name %u.\n", i, device->dummy_texture_2d[i]); + TRACE("Dummy rectangle texture given name %u.\n", device->dummy_textures.tex_rect); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); checkGLcall("glBindTexture"); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); checkGLcall("glTexImage2D"); - - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_rect[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy rectangle texture %u given name %u.\n", i, device->dummy_texture_rect[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]); - checkGLcall("glBindTexture"); - - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); - checkGLcall("glTexImage2D"); - } - - if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_3d[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy 3D texture %u given name %u.\n", i, device->dummy_texture_3d[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]); - checkGLcall("glBindTexture"); - - GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); - checkGLcall("glTexImage3D"); - } - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_cube[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy cube texture %u given name %u.\n", i, device->dummy_texture_cube[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]); - checkGLcall("glBindTexture"); - - for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++j) - { - gl_info->gl_ops.gl.p_glTexImage2D(j, 0, GL_RGBA8, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); - checkGLcall("glTexImage2D"); - } - } - } -} - -/* Context activation is done by the caller. */ -static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) -{ - unsigned int count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_cube); - checkGLcall("glDeleteTextures(count, device->dummy_texture_cube)"); } if (gl_info->supported[EXT_TEXTURE3D]) { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_3d); - checkGLcall("glDeleteTextures(count, device->dummy_texture_3d)"); + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_3d); + checkGLcall("glGenTextures"); + TRACE("Dummy 3D texture given name %u.\n", device->dummy_textures.tex_3d); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); + checkGLcall("glBindTexture"); + + GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); + checkGLcall("glTexImage3D"); } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_rect); - checkGLcall("glDeleteTextures(count, device->dummy_texture_rect)"); + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_cube); + checkGLcall("glGenTextures"); + TRACE("Dummy cube texture given name %u.\n", device->dummy_textures.tex_cube); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); + checkGLcall("glBindTexture"); + + for (i = GL_TEXTURE_CUBE_MAP_POSITIVE_X; i <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++i) + { + gl_info->gl_ops.gl.p_glTexImage2D(i, 0, GL_RGBA8, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + checkGLcall("glTexImage2D"); + } } - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_2d); - checkGLcall("glDeleteTextures(count, device->dummy_texture_2d)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) + { + DWORD cube_array_data[6]; - memset(device->dummy_texture_cube, 0, count * sizeof(*device->dummy_texture_cube)); - memset(device->dummy_texture_3d, 0, count * sizeof(*device->dummy_texture_3d)); - memset(device->dummy_texture_rect, 0, count * sizeof(*device->dummy_texture_rect)); - memset(device->dummy_texture_2d, 0, count * sizeof(*device->dummy_texture_2d)); + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_cube_array); + checkGLcall("glGenTextures"); + TRACE("Dummy cube array texture given name %u.\n", device->dummy_textures.tex_cube_array); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, device->dummy_textures.tex_cube_array); + checkGLcall("glBindTexture"); + + for (i = 0; i < ARRAY_SIZE(cube_array_data); ++i) + cube_array_data[i] = color; + GL_EXTCALL(glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA8, 1, 1, 6, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, cube_array_data)); + checkGLcall("glTexImage3D"); + } + + if (gl_info->supported[EXT_TEXTURE_ARRAY]) + { + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_1d_array); + checkGLcall("glGenTextures"); + TRACE("Dummy 1D array texture given name %u.\n", device->dummy_textures.tex_1d_array); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, device->dummy_textures.tex_1d_array); + checkGLcall("glBindTexture"); + + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + checkGLcall("glTexImage2D"); + + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d_array); + checkGLcall("glGenTextures"); + TRACE("Dummy 2D array texture given name %u.\n", device->dummy_textures.tex_2d_array); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); + checkGLcall("glBindTexture"); + + GL_EXTCALL(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); + checkGLcall("glTexImage3D"); + } + + if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) + { + GLuint buffer; + + GL_EXTCALL(glGenBuffers(1, &buffer)); + GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, buffer)); + GL_EXTCALL(glBufferData(GL_TEXTURE_BUFFER, sizeof(color), &color, GL_STATIC_DRAW)); + GL_EXTCALL(glBindBuffer(GL_TEXTURE_BUFFER, 0)); + checkGLcall("Create buffer object"); + + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_buffer); + checkGLcall("glGenTextures"); + TRACE("Dummy buffer texture given name %u.\n", device->dummy_textures.tex_buffer); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, device->dummy_textures.tex_buffer); + checkGLcall("glBindTexture"); + GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, buffer)); + checkGLcall("glTexBuffer"); + + GL_EXTCALL(glDeleteBuffers(1, &buffer)); + checkGLcall("glDeleteBuffers"); + } + + context_bind_dummy_textures(device, context); } /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -void device_create_default_sampler(struct wined3d_device *device) -#else /* STAGING_CSMT */ -static void create_default_sampler(struct wined3d_device *device) -#endif /* STAGING_CSMT */ +static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info = context->gl_info; - /* - * In SM4+ shaders there is a separation between resources and samplers. Some of shader - * instructions allow to access resources without using samplers. - * In GLSL resources are always accessed through sampler or image variables. The default + if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_buffer); + + if (gl_info->supported[EXT_TEXTURE_ARRAY]) + { + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d_array); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_1d_array); + } + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_cube_array); + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_cube); + + if (gl_info->supported[EXT_TEXTURE3D]) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_3d); + + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_rect); + + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_1d); + + checkGLcall("Delete dummy textures"); + + memset(&device->dummy_textures, 0, sizeof(device->dummy_textures)); +} + +/* Context activation is done by the caller. */ +static void create_default_samplers(struct wined3d_device *device, struct wined3d_context *context) +{ + struct wined3d_sampler_desc desc; + HRESULT hr; + + desc.address_u = WINED3D_TADDRESS_WRAP; + desc.address_v = WINED3D_TADDRESS_WRAP; + desc.address_w = WINED3D_TADDRESS_WRAP; + memset(desc.border_color, 0, sizeof(desc.border_color)); + desc.mag_filter = WINED3D_TEXF_POINT; + desc.min_filter = WINED3D_TEXF_POINT; + desc.mip_filter = WINED3D_TEXF_NONE; + desc.lod_bias = 0.0f; + desc.min_lod = -1000.0f; + desc.max_lod = 1000.0f; + desc.mip_base_level = 0; + desc.max_anisotropy = 1; + desc.compare = FALSE; + desc.comparison_func = WINED3D_CMP_NEVER; + desc.srgb_decode = TRUE; + + /* In SM4+ shaders there is a separation between resources and samplers. Some shader + * instructions allow access to resources without using samplers. + * In GLSL, resources are always accessed through sampler or image variables. The default * sampler object is used to emulate the direct resource access when there is no sampler state * to use. */ - - if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + if (FAILED(hr = wined3d_sampler_create(device, &desc, NULL, &wined3d_null_parent_ops, &device->default_sampler))) { - GL_EXTCALL(glGenSamplers(1, &device->default_sampler)); - checkGLcall("glGenSamplers"); - GL_EXTCALL(glSamplerParameteri(device->default_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_EXTCALL(glSamplerParameteri(device->default_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); - checkGLcall("glSamplerParamteri"); + ERR("Failed to create default sampler, hr %#x.\n", hr); + device->default_sampler = NULL; } - else + + /* In D3D10+, a NULL sampler maps to the default sampler state. */ + desc.address_u = WINED3D_TADDRESS_CLAMP; + desc.address_v = WINED3D_TADDRESS_CLAMP; + desc.address_w = WINED3D_TADDRESS_CLAMP; + desc.mag_filter = WINED3D_TEXF_LINEAR; + desc.min_filter = WINED3D_TEXF_LINEAR; + desc.mip_filter = WINED3D_TEXF_LINEAR; + if (FAILED(hr = wined3d_sampler_create(device, &desc, NULL, &wined3d_null_parent_ops, &device->null_sampler))) { - device->default_sampler = 0; + ERR("Failed to create null sampler, hr %#x.\n", hr); + device->null_sampler = NULL; } } /* Context activation is done by the caller. */ -static void destroy_default_sampler(struct wined3d_device *device) +static void destroy_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - - if (gl_info->supported[ARB_SAMPLER_OBJECTS]) - { - GL_EXTCALL(glDeleteSamplers(1, &device->default_sampler)); - checkGLcall("glDeleteSamplers"); - } - - device->default_sampler = 0; + wined3d_sampler_decref(device->default_sampler); + device->default_sampler = NULL; + wined3d_sampler_decref(device->null_sampler); + device->null_sampler = NULL; } static LONG fullscreen_style(LONG style) @@ -883,12 +888,16 @@ void CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, device->filter_messages = filter_messages; } -void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window) +void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, + const RECT *window_rect) { + unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; BOOL filter_messages; LONG style, exstyle; + RECT rect = {0}; - if (!device->style && !device->exStyle) return; + if (!device->style && !device->exStyle) + return; style = GetWindowLongW(window, GWL_STYLE); exstyle = GetWindowLongW(window, GWL_EXSTYLE); @@ -917,7 +926,13 @@ void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *devic SetWindowLongW(window, GWL_STYLE, device->style); SetWindowLongW(window, GWL_EXSTYLE, device->exStyle); } - SetWindowPos(window, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + if (window_rect) + rect = *window_rect; + else + window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(window, 0, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); device->filter_messages = filter_messages; @@ -955,11 +970,7 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil; unsigned int i; -#if defined(STAGING_CSMT) - if (device->state.fb.render_targets) -#else /* STAGING_CSMT */ if (device->fb.render_targets) -#endif /* STAGING_CSMT */ { for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) { @@ -973,17 +984,95 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi wined3d_device_set_render_state(device, WINED3D_RS_ZENABLE, ds_enable); } +static void wined3d_device_delete_opengl_contexts_cs(void *object) +{ + struct wined3d_resource *resource, *cursor; + struct wined3d_device *device = object; + struct wined3d_context *context; + struct wined3d_shader *shader; + + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Unloading resource %p.\n", resource); + wined3d_cs_emit_unload_resource(device->cs, resource); + } + + LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) + { + device->shader_backend->shader_destroy(shader); + } + + context = context_acquire(device, NULL, 0); + device->blitter->ops->blitter_destroy(device->blitter, context); + device->shader_backend->shader_free_private(device); + destroy_dummy_textures(device, context); + destroy_default_samplers(device, context); + context_release(context); + + while (device->context_count) + { + if (device->contexts[0]->swapchain) + swapchain_destroy_contexts(device->contexts[0]->swapchain); + else + context_destroy(device, device->contexts[0]); + } +} + +static void wined3d_device_delete_opengl_contexts(struct wined3d_device *device) +{ + wined3d_cs_destroy_object(device->cs, wined3d_device_delete_opengl_contexts_cs, device); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); +} + +static void wined3d_device_create_primary_opengl_context_cs(void *object) +{ + struct wined3d_device *device = object; + struct wined3d_swapchain *swapchain; + struct wined3d_context *context; + struct wined3d_texture *target; + HRESULT hr; + + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, + device->adapter->vertex_pipe, device->adapter->fragment_pipe))) + { + ERR("Failed to allocate shader private data, hr %#x.\n", hr); + return; + } + + if (!(device->blitter = wined3d_cpu_blitter_create())) + { + ERR("Failed to create CPU blitter.\n"); + device->shader_backend->shader_free_private(device); + return; + } + wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info); + wined3d_arbfp_blitter_create(&device->blitter, device); + wined3d_fbo_blitter_create(&device->blitter, &device->adapter->gl_info); + + swapchain = device->swapchains[0]; + target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer; + context = context_acquire(device, target, 0); + create_dummy_textures(device, context); + create_default_samplers(device, context); + context_release(context); +} + +static HRESULT wined3d_device_create_primary_opengl_context(struct wined3d_device *device) +{ + wined3d_cs_init_object(device->cs, wined3d_device_create_primary_opengl_context_cs, device); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!device->swapchains[0]->num_contexts) + return E_FAIL; + + return WINED3D_OK; +} + HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc) { static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; -#if defined(STAGING_CSMT) - struct wined3d_swapchain *swapchain = NULL; -#else /* STAGING_CSMT */ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_swapchain *swapchain = NULL; - struct wined3d_context *context; -#endif /* STAGING_CSMT */ DWORD clear_flags = 0; HRESULT hr; @@ -994,22 +1083,8 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, if (device->wined3d->flags & WINED3D_NO3D) return WINED3DERR_INVALIDCALL; -#if !defined(STAGING_CSMT) - device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*device->fb.render_targets) * gl_info->limits.buffers); - -#endif /* STAGING_CSMT */ - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, - device->adapter->vertex_pipe, device->adapter->fragment_pipe))) - { - TRACE("Shader private data couldn't be allocated\n"); - goto err_out; - } - if (FAILED(hr = device->blitter->alloc_private(device))) - { - TRACE("Blitter private data couldn't be allocated\n"); - goto err_out; - } + if (!(device->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*device->fb.render_targets)))) + return E_OUTOFMEMORY; /* Setup the implicit swapchain. This also initializes a context. */ TRACE("Creating implicit swapchain\n"); @@ -1023,13 +1098,16 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, if (swapchain_desc->backbuffer_count) { - struct wined3d_rendertarget_view_desc view_desc; + struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; + struct wined3d_view_desc view_desc; - view_desc.format_id = swapchain_desc->backbuffer_format; + view_desc.format_id = back_buffer->format->id; + view_desc.flags = 0; view_desc.u.texture.level_idx = 0; + view_desc.u.texture.level_count = 1; view_desc.u.texture.layer_idx = 0; view_desc.u.texture.layer_count = 1; - if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, &swapchain->back_buffers[0]->resource, + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, back_buffer, NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); @@ -1038,62 +1116,20 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, } device->swapchain_count = 1; - device->swapchains = HeapAlloc(GetProcessHeap(), 0, device->swapchain_count * sizeof(*device->swapchains)); - if (!device->swapchains) + if (!(device->swapchains = wined3d_calloc(device->swapchain_count, sizeof(*device->swapchains)))) { ERR("Out of memory!\n"); goto err_out; } device->swapchains[0] = swapchain; + + if (FAILED(hr = wined3d_device_create_primary_opengl_context(device))) + goto err_out; device_init_swapchain_state(device, swapchain); -#if defined(STAGING_CSMT) - /* also calls create_default_sampler */ - wined3d_cs_emit_create_dummy_textures(device->cs); -#else /* STAGING_CSMT */ - context = context_acquire(device, - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); - - create_dummy_textures(device, context); - create_default_sampler(device); -#endif /* STAGING_CSMT */ - device->contexts[0]->last_was_rhw = 0; - switch (wined3d_settings.offscreen_rendering_mode) - { - case ORM_FBO: - device->offscreenBuffer = GL_COLOR_ATTACHMENT0; - break; - - case ORM_BACKBUFFER: - { -#if defined(STAGING_CSMT) - if (device->contexts[0]->aux_buffers > 0) -#else /* STAGING_CSMT */ - if (context_get_current()->aux_buffers > 0) -#endif /* STAGING_CSMT */ - { - TRACE("Using auxiliary buffer for offscreen rendering\n"); - device->offscreenBuffer = GL_AUX0; - } - else - { - TRACE("Using back buffer for offscreen rendering\n"); - device->offscreenBuffer = GL_BACK; - } - } - } -#if defined(STAGING_CSMT) - device->contexts[0]->offscreenBuffer = device->offscreenBuffer; - TRACE("All defaults now set up, leaving 3D init.\n"); -#else /* STAGING_CSMT */ - - TRACE("All defaults now set up, leaving 3D init.\n"); - - context_release(context); -#endif /* STAGING_CSMT */ /* Clear the screen */ if (swapchain->back_buffers && swapchain->back_buffers[0]) @@ -1110,19 +1146,13 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, return WINED3D_OK; err_out: -#if !defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, device->fb.render_targets); -#endif /* STAGING_CSMT */ HeapFree(GetProcessHeap(), 0, device->swapchains); device->swapchain_count = 0; if (device->back_buffer_view) wined3d_rendertarget_view_decref(device->back_buffer_view); if (swapchain) wined3d_swapchain_decref(swapchain); - if (device->blit_priv) - device->blitter->free_private(device); - if (device->shader_priv) - device->shader_backend->shader_free_private(device); + HeapFree(GetProcessHeap(), 0, device->fb.render_targets); return hr; } @@ -1146,8 +1176,7 @@ HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device, } device->swapchain_count = 1; - device->swapchains = HeapAlloc(GetProcessHeap(), 0, device->swapchain_count * sizeof(*device->swapchains)); - if (!device->swapchains) + if (!(device->swapchains = wined3d_calloc(device->swapchain_count, sizeof(*device->swapchains)))) { ERR("Out of memory!\n"); goto err_out; @@ -1169,12 +1198,6 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context) HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) { - struct wined3d_resource *resource, *cursor; -#if !defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; -#endif /* STAGING_CSMT */ - struct wined3d_surface *surface; UINT i; TRACE("device %p.\n", device); @@ -1182,51 +1205,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) if (!device->d3d_initialized) return WINED3DERR_INVALIDCALL; -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - device->cs->ops->finish(device->cs); - - if (device->logo_texture) - wined3d_texture_decref(device->logo_texture); - - /* Release the buffers (with sanity checks). - * FIXME: Move this move into a separate patch. I think the idea - * behind this is that those surfaces should be freed before unloading - * remaining resources below. - * FIXME 2: Shouldn't the cs take care of onscreen_depth_stencil? */ - if (device->cs->onscreen_depth_stencil) - { - surface = device->cs->onscreen_depth_stencil; - device->cs->onscreen_depth_stencil = NULL; - wined3d_texture_decref(surface->container); - } - - state_unbind_resources(&device->state); - - if (device->auto_depth_stencil_view) - { - wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); - device->auto_depth_stencil_view = NULL; - } - - /* Unload resources */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - wined3d_cs_emit_evict_resource(device->cs, resource); - } - - wine_rb_clear(&device->samplers, device_free_sampler, NULL); - - /* FIXME: Is this in the right place??? */ - wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]); - -#else /* STAGING_CSMT */ - /* I don't think that the interface guarantees that the device is destroyed from the same thread - * it was created. Thus make sure a context is active for the glDelete* calls - */ - context = context_acquire(device, NULL); - gl_info = context->gl_info; + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); if (device->logo_texture) wined3d_texture_decref(device->logo_texture); @@ -1235,44 +1214,12 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) state_unbind_resources(&device->state); - /* Unload resources */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - - resource->resource_ops->resource_unload(resource); - } - wine_rb_clear(&device->samplers, device_free_sampler, NULL); - /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader - * private data, it might contain opengl pointers - */ - if (device->depth_blt_texture) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); - device->depth_blt_texture = 0; - } - - /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); - destroy_default_sampler(device); - - /* Release the context again as soon as possible. In particular, - * releasing the render target views below may release the last reference - * to the swapchain associated with this context, which in turn will - * destroy the context. */ - context_release(context); - - /* Release the buffers (with sanity checks)*/ - if (device->onscreen_depth_stencil) - { - surface = device->onscreen_depth_stencil; - device->onscreen_depth_stencil = NULL; - wined3d_texture_decref(surface->container); - } +#if defined(STAGING_CSMT) + context_set_current(NULL); +#endif /* STAGING_CSMT */ + wined3d_device_delete_opengl_contexts(device); if (device->fb.depth_stencil) { @@ -1293,11 +1240,10 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) ERR("Something's still holding the auto depth/stencil view (%p).\n", view); } - for (i = 0; i < gl_info->limits.buffers; ++i) + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) { wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); } -#endif /* STAGING_CSMT */ if (device->back_buffer_view) { wined3d_rendertarget_view_decref(device->back_buffer_view); @@ -1315,11 +1261,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) device->swapchains = NULL; device->swapchain_count = 0; -#if !defined(STAGING_CSMT) HeapFree(GetProcessHeap(), 0, device->fb.render_targets); device->fb.render_targets = NULL; -#endif /* STAGING_CSMT */ device->d3d_initialized = FALSE; return WINED3D_OK; @@ -1358,18 +1302,19 @@ void CDECL wined3d_device_set_multithreaded(struct wined3d_device *device) UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + /* const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; */ TRACE("device %p.\n", device); /* We can not acquire the context unless there is a swapchain. */ + /* if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] && !wined3d_settings.emulated_textureram) { GLint vram_free_kb; UINT64 vram_free; - struct wined3d_context *context = context_acquire(device, NULL); + struct wined3d_context *context = context_acquire(device, NULL, 0); gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &vram_free_kb); vram_free = (UINT64)vram_free_kb * 1024; context_release(context); @@ -1382,6 +1327,7 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device vram_free = min(vram_free, device->adapter->vram_bytes - device->adapter->vram_bytes_used); return min(UINT_MAX, vram_free); } + */ TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n", wine_dbgstr_longlong(device->adapter->vram_bytes), @@ -1399,7 +1345,7 @@ void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT TRACE("device %p, idx %u, buffer %p, offset %u.\n", device, idx, buffer, offset); - if (idx >= MAX_STREAM_OUT) + if (idx >= WINED3D_MAX_STREAM_OUTPUT_BUFFERS) { WARN("Invalid stream output %u.\n", idx); return; @@ -1423,7 +1369,7 @@ struct wined3d_buffer * CDECL wined3d_device_get_stream_output(struct wined3d_de { TRACE("device %p, idx %u, offset %p.\n", device, idx, offset); - if (idx >= MAX_STREAM_OUT) + if (idx >= WINED3D_MAX_STREAM_OUTPUT_BUFFERS) { WARN("Invalid stream output %u.\n", idx); return NULL; @@ -1641,7 +1587,6 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, { UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); struct wined3d_light_info *object = NULL; - struct list *e; float rho; TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light); @@ -1675,15 +1620,7 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; } - LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx]) - { - object = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (object->OriginalIndex == light_idx) - break; - object = NULL; - } - - if (!object) + if (!(object = wined3d_state_get_light(device->update_state, light_idx))) { TRACE("Adding new light\n"); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); @@ -1696,26 +1633,15 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, } /* Initialize the object. */ - TRACE("Light %d setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", - light_idx, light->type, - light->diffuse.r, light->diffuse.g, light->diffuse.b, light->diffuse.a, - light->specular.r, light->specular.g, light->specular.b, light->specular.a, - light->ambient.r, light->ambient.g, light->ambient.b, light->ambient.a); - TRACE("... Pos(%f,%f,%f), Dir(%f,%f,%f)\n", light->position.x, light->position.y, light->position.z, - light->direction.x, light->direction.y, light->direction.z); - TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", + TRACE("Light %u setting to type %#x, diffuse %s, specular %s, ambient %s, " + "position {%.8e, %.8e, %.8e}, direction {%.8e, %.8e, %.8e}, " + "range %.8e, falloff %.8e, theta %.8e, phi %.8e.\n", + light_idx, light->type, debug_color(&light->diffuse), + debug_color(&light->specular), debug_color(&light->ambient), + light->position.x, light->position.y, light->position.z, + light->direction.x, light->direction.y, light->direction.z, light->range, light->falloff, light->theta, light->phi); -#if !defined(STAGING_CSMT) - /* Update the live definitions if the light is currently assigned a glIndex. */ - if (object->glIndex != -1 && !device->recording) - { - if (object->OriginalParms.type != light->type) - device_invalidate_state(device, STATE_LIGHT_TYPE); - device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex)); - } - -#endif /* STAGING_CSMT */ /* Save away the information. */ object->OriginalParms = *light; @@ -1795,32 +1721,20 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, FIXME("Unrecognized light type %#x.\n", light->type); } -#if defined(STAGING_CSMT) if (!device->recording) wined3d_cs_emit_set_light(device->cs, object); -#endif /* STAGING_CSMT */ return WINED3D_OK; } HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device, UINT light_idx, struct wined3d_light *light) { - UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); - struct wined3d_light_info *light_info = NULL; - struct list *e; + struct wined3d_light_info *light_info; TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light); - LIST_FOR_EACH(e, &device->state.light_map[hash_idx]) - { - light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (light_info->OriginalIndex == light_idx) - break; - light_info = NULL; - } - - if (!light_info) + if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) { TRACE("Light information requested but light not defined\n"); return WINED3DERR_INVALIDCALL; @@ -1832,133 +1746,37 @@ HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device, HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable) { - UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); - struct wined3d_light_info *light_info = NULL; - struct list *e; + struct wined3d_light_info *light_info; TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable); - LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx]) - { - light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (light_info->OriginalIndex == light_idx) - break; - light_info = NULL; - } - TRACE("Found light %p.\n", light_info); - /* Special case - enabling an undefined light creates one with a strict set of parameters. */ - if (!light_info) + if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) { TRACE("Light enabled requested but light not defined, so defining one!\n"); wined3d_device_set_light(device, light_idx, &WINED3D_default_light); - /* Search for it again! Should be fairly quick as near head of list. */ - LIST_FOR_EACH(e, &device->update_state->light_map[hash_idx]) - { - light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (light_info->OriginalIndex == light_idx) - break; - light_info = NULL; - } - if (!light_info) + if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) { FIXME("Adding default lights has failed dismally\n"); return WINED3DERR_INVALIDCALL; } } - if (!enable) - { - if (light_info->glIndex != -1) - { -#if !defined(STAGING_CSMT) - if (!device->recording) - { - device_invalidate_state(device, STATE_LIGHT_TYPE); - device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); - } - -#endif /* STAGING_CSMT */ - device->update_state->lights[light_info->glIndex] = NULL; - light_info->glIndex = -1; - } - else - { - TRACE("Light already disabled, nothing to do\n"); - } - light_info->enabled = FALSE; - } - else - { - light_info->enabled = TRUE; - if (light_info->glIndex != -1) - { - TRACE("Nothing to do as light was enabled\n"); - } - else - { - unsigned int i; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - /* Find a free GL light. */ - for (i = 0; i < gl_info->limits.lights; ++i) - { - if (!device->update_state->lights[i]) - { - device->update_state->lights[i] = light_info; - light_info->glIndex = i; - break; - } - } - if (light_info->glIndex == -1) - { - /* Our tests show that Windows returns D3D_OK in this situation, even with - * D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE devices. This - * is consistent among ddraw, d3d8 and d3d9. GetLightEnable returns TRUE - * as well for those lights. - * - * TODO: Test how this affects rendering. */ - WARN("Too many concurrently active lights\n"); - return WINED3D_OK; - } -#if defined(STAGING_CSMT) - } - } - + wined3d_state_enable_light(device->update_state, &device->adapter->d3d_info, light_info, enable); if (!device->recording) wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); -#else /* STAGING_CSMT */ - - /* i == light_info->glIndex */ - if (!device->recording) - { - device_invalidate_state(device, STATE_LIGHT_TYPE); - device_invalidate_state(device, STATE_ACTIVELIGHT(i)); - } - } - } -#endif /* STAGING_CSMT */ return WINED3D_OK; } HRESULT CDECL wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable) { - UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); - struct wined3d_light_info *light_info = NULL; - struct list *e; + struct wined3d_light_info *light_info; TRACE("device %p, light_idx %u, enable %p.\n", device, light_idx, enable); - LIST_FOR_EACH(e, &device->state.light_map[hash_idx]) - { - light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); - if (light_info->OriginalIndex == light_idx) - break; - light_info = NULL; - } - - if (!light_info) + if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) { TRACE("Light enabled state requested but light not defined.\n"); return WINED3DERR_INVALIDCALL; @@ -1974,7 +1792,7 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device, TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.clipplanes) + if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; @@ -2003,7 +1821,7 @@ HRESULT CDECL wined3d_device_get_clip_plane(const struct wined3d_device *device, TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.clipplanes) + if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; @@ -2054,56 +1872,53 @@ void CDECL wined3d_device_get_material(const struct wined3d_device *device, stru *material = device->state.material; - TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n", - material->diffuse.r, material->diffuse.g, - material->diffuse.b, material->diffuse.a); - TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n", - material->ambient.r, material->ambient.g, - material->ambient.b, material->ambient.a); - TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n", - material->specular.r, material->specular.g, - material->specular.b, material->specular.a); - TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n", - material->emissive.r, material->emissive.g, - material->emissive.b, material->emissive.a); + TRACE("diffuse %s\n", debug_color(&material->diffuse)); + TRACE("ambient %s\n", debug_color(&material->ambient)); + TRACE("specular %s\n", debug_color(&material->specular)); + TRACE("emissive %s\n", debug_color(&material->emissive)); TRACE("power %.8e.\n", material->power); } void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, - struct wined3d_buffer *buffer, enum wined3d_format_id format_id) + struct wined3d_buffer *buffer, enum wined3d_format_id format_id, unsigned int offset) { enum wined3d_format_id prev_format; struct wined3d_buffer *prev_buffer; + unsigned int prev_offset; - TRACE("device %p, buffer %p, format %s.\n", - device, buffer, debug_d3dformat(format_id)); + TRACE("device %p, buffer %p, format %s, offset %u.\n", + device, buffer, debug_d3dformat(format_id), offset); prev_buffer = device->update_state->index_buffer; prev_format = device->update_state->index_format; + prev_offset = device->update_state->index_offset; device->update_state->index_buffer = buffer; device->update_state->index_format = format_id; + device->update_state->index_offset = offset; if (device->recording) device->recording->changed.indices = TRUE; - if (prev_buffer == buffer && prev_format == format_id) + if (prev_buffer == buffer && prev_format == format_id && prev_offset == offset) return; if (buffer) wined3d_buffer_incref(buffer); if (!device->recording) - wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id); + wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id, offset); if (prev_buffer) wined3d_buffer_decref(prev_buffer); } struct wined3d_buffer * CDECL wined3d_device_get_index_buffer(const struct wined3d_device *device, - enum wined3d_format_id *format) + enum wined3d_format_id *format, unsigned int *offset) { - TRACE("device %p, format %p.\n", device, format); + TRACE("device %p, format %p, offset %p.\n", device, format, offset); *format = device->state.index_format; + if (offset) + *offset = device->state.index_offset; return device->state.index_buffer; } @@ -2112,11 +1927,6 @@ void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, I TRACE("device %p, base_index %d.\n", device, base_index); device->update_state->base_vertex_index = base_index; -#if defined(STAGING_CSMT) - - if (!device->recording) - wined3d_cs_emit_set_base_vertex_index(device->cs, base_index); -#endif /* STAGING_CSMT */ } INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) @@ -2129,7 +1939,7 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport) { TRACE("device %p, viewport %p.\n", device, viewport); - TRACE("x %u, y %u, w %u, h %u, min_z %.8e, max_z %.8e.\n", + TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z); device->update_state->viewport = *viewport; @@ -2162,11 +1972,7 @@ static void resolve_depth_buffer(struct wined3d_state *state) || !(dst_texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) return; -#if defined(STAGING_CSMT) - if (!(src_view = state->fb.depth_stencil)) -#else /* STAGING_CSMT */ if (!(src_view = state->fb->depth_stencil)) -#endif /* STAGING_CSMT */ return; if (src_view->resource->type == WINED3D_RTYPE_BUFFER) { @@ -2176,10 +1982,36 @@ static void resolve_depth_buffer(struct wined3d_state *state) SetRect(&dst_rect, 0, 0, dst_texture->resource.width, dst_texture->resource.height); SetRect(&src_rect, 0, 0, src_view->width, src_view->height); - wined3d_texture_blt(dst_texture, 0, &dst_rect, wined3d_texture_from_resource(src_view->resource), + wined3d_texture_blt(dst_texture, 0, &dst_rect, texture_from_resource(src_view->resource), src_view->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); } +void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, + struct wined3d_rasterizer_state *rasterizer_state) +{ + struct wined3d_rasterizer_state *prev; + + TRACE("device %p, rasterizer_state %p.\n", device, rasterizer_state); + + prev = device->update_state->rasterizer_state; + if (prev == rasterizer_state) + return; + + if (rasterizer_state) + wined3d_rasterizer_state_incref(rasterizer_state); + device->update_state->rasterizer_state = rasterizer_state; + wined3d_cs_emit_set_rasterizer_state(device->cs, rasterizer_state); + if (prev) + wined3d_rasterizer_state_decref(prev); +} + +struct wined3d_rasterizer_state * CDECL wined3d_device_get_rasterizer_state(struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.rasterizer_state; +} + void CDECL wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value) { @@ -2398,17 +2230,23 @@ void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, str wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_VERTEX, idx, buffer); } -struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx) +static struct wined3d_buffer *wined3d_device_get_constant_buffer(const struct wined3d_device *device, + enum wined3d_shader_type shader_type, unsigned int idx) { - TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_CONSTANT_BUFFERS) { WARN("Invalid constant buffer index %u.\n", idx); return NULL; } - return device->state.cb[WINED3D_SHADER_TYPE_VERTEX][idx]; + return device->state.cb[shader_type][idx]; +} + +struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_VERTEX, idx); } static void wined3d_device_set_shader_resource_view(struct wined3d_device *device, @@ -2443,18 +2281,24 @@ void CDECL wined3d_device_set_vs_resource_view(struct wined3d_device *device, wined3d_device_set_shader_resource_view(device, WINED3D_SHADER_TYPE_VERTEX, idx, view); } -struct wined3d_shader_resource_view * CDECL wined3d_device_get_vs_resource_view(const struct wined3d_device *device, - UINT idx) +static struct wined3d_shader_resource_view *wined3d_device_get_shader_resource_view( + const struct wined3d_device *device, enum wined3d_shader_type shader_type, unsigned int idx) { - TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SHADER_RESOURCE_VIEWS) { WARN("Invalid view index %u.\n", idx); return NULL; } - return device->state.shader_resource_view[WINED3D_SHADER_TYPE_VERTEX][idx]; + return device->state.shader_resource_view[shader_type][idx]; +} + +struct wined3d_shader_resource_view * CDECL wined3d_device_get_vs_resource_view(const struct wined3d_device *device, + UINT idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_VERTEX, idx); } static void wined3d_device_set_sampler(struct wined3d_device *device, @@ -2488,188 +2332,164 @@ void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_VERTEX, idx, sampler); } -struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx) +static struct wined3d_sampler *wined3d_device_get_sampler(const struct wined3d_device *device, + enum wined3d_shader_type shader_type, unsigned int idx) { - TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SAMPLER_OBJECTS) { WARN("Invalid sampler index %u.\n", idx); return NULL; } - return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; + return device->state.sampler[shader_type][idx]; } -#if defined(STAGING_CSMT) -void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) -#else /* STAGING_CSMT */ -static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) -#endif /* STAGING_CSMT */ +struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx) { - UINT i; + TRACE("device %p, idx %u.\n", device, idx); - for (i = 0; i < device->context_count; ++i) - { - device->contexts[i]->constant_update_mask |= mask; - } + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_VERTEX, idx); } HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device, - UINT start_register, const BOOL *constants, UINT bool_count) + unsigned int start_idx, unsigned int count, const BOOL *constants) { - UINT count = min(bool_count, MAX_CONST_B - start_register); - UINT i; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, bool_count %u.\n", - device, start_register, constants, bool_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || start_register >= MAX_CONST_B) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->vs_consts_b[start_register], constants, count * sizeof(BOOL)); - for (i = 0; i < count; ++i) - TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false"); + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + memcpy(&device->update_state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) + { + for (i = 0; i < count; ++i) + TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); + } if (device->recording) { - for (i = start_register; i < count + start_register; ++i) + for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.vertexShaderConstantsB |= (1u << i); } else { -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, - bool_count, WINED3D_SHADER_TYPE_VERTEX); -#else /* STAGING_CSMT */ - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants); } return WINED3D_OK; } HRESULT CDECL wined3d_device_get_vs_consts_b(const struct wined3d_device *device, - UINT start_register, BOOL *constants, UINT bool_count) + unsigned int start_idx, unsigned int count, BOOL *constants) { - UINT count = min(bool_count, MAX_CONST_B - start_register); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - TRACE("device %p, start_register %u, constants %p, bool_count %u.\n", - device, start_register, constants, bool_count); - - if (!constants || start_register >= MAX_CONST_B) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.vs_consts_b[start_register], count * sizeof(BOOL)); + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + memcpy(constants, &device->state.vs_consts_b[start_idx], count * sizeof(*constants)); return WINED3D_OK; } HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device, - UINT start_register, const int *constants, UINT vector4i_count) + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants) { - UINT count = min(vector4i_count, MAX_CONST_I - start_register); - UINT i; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n", - device, start_register, constants, vector4i_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || start_register >= MAX_CONST_I) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->vs_consts_i[start_register * 4], constants, count * sizeof(int) * 4); - for (i = 0; i < count; ++i) - TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i, - constants[i * 4], constants[i * 4 + 1], - constants[i * 4 + 2], constants[i * 4 + 3]); + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + memcpy(&device->update_state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) + { + for (i = 0; i < count; ++i) + TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); + } if (device->recording) { - for (i = start_register; i < count + start_register; ++i) + for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.vertexShaderConstantsI |= (1u << i); } else { -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, - vector4i_count, WINED3D_SHADER_TYPE_VERTEX); -#else /* STAGING_CSMT */ - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants); } return WINED3D_OK; } HRESULT CDECL wined3d_device_get_vs_consts_i(const struct wined3d_device *device, - UINT start_register, int *constants, UINT vector4i_count) + unsigned int start_idx, unsigned int count, struct wined3d_ivec4 *constants) { - UINT count = min(vector4i_count, MAX_CONST_I - start_register); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n", - device, start_register, constants, vector4i_count); - - if (!constants || start_register >= MAX_CONST_I) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.vs_consts_i[start_register * 4], count * sizeof(int) * 4); + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + memcpy(constants, &device->state.vs_consts_i[start_idx], count * sizeof(*constants)); return WINED3D_OK; } HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, - UINT start_register, const float *constants, UINT vector4f_count) + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) { - UINT i; const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n", - device, start_register, constants, vector4f_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - /* Specifically test start_register > limit to catch MAX_UINT overflows - * when adding start_register + vector4f_count. */ - if (!constants - || start_register + vector4f_count > d3d_info->limits.vs_uniform_count - || start_register > d3d_info->limits.vs_uniform_count) + if (!constants || start_idx >= d3d_info->limits.vs_uniform_count + || count > d3d_info->limits.vs_uniform_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->vs_consts_f[start_register * 4], - constants, vector4f_count * sizeof(float) * 4); + memcpy(&device->update_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { - for (i = 0; i < vector4f_count; ++i) - TRACE("Set FLOAT constant %u to {%.8e, %.8e, %.8e, %.8e}.\n", start_register + i, - constants[i * 4], constants[i * 4 + 1], - constants[i * 4 + 2], constants[i * 4 + 3]); + for (i = 0; i < count; ++i) + TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); } if (device->recording) - memset(device->recording->changed.vertexShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count); + memset(&device->recording->changed.vs_consts_f[start_idx], 1, + count * sizeof(*device->recording->changed.vs_consts_f)); else -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, - WINED3D_SHADER_TYPE_VERTEX); -#else /* STAGING_CSMT */ - device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count); - -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants); return WINED3D_OK; } HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device, - UINT start_register, float *constants, UINT vector4f_count) + unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - int count = min(vector4f_count, d3d_info->limits.vs_uniform_count - start_register); - TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n", - device, start_register, constants, vector4f_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || count < 0) + if (!constants || start_idx >= d3d_info->limits.vs_uniform_count + || count > d3d_info->limits.vs_uniform_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.vs_consts_f[start_register * 4], count * sizeof(float) * 4); + memcpy(constants, &device->state.vs_consts_f[start_idx], count * sizeof(*constants)); return WINED3D_OK; } @@ -2713,13 +2533,7 @@ struct wined3d_buffer * CDECL wined3d_device_get_ps_cb(const struct wined3d_devi { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_CONSTANT_BUFFERS) - { - WARN("Invalid constant buffer index %u.\n", idx); - return NULL; - } - - return device->state.cb[WINED3D_SHADER_TYPE_PIXEL][idx]; + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_PIXEL, idx); } void CDECL wined3d_device_set_ps_resource_view(struct wined3d_device *device, @@ -2735,13 +2549,7 @@ struct wined3d_shader_resource_view * CDECL wined3d_device_get_ps_resource_view( { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SHADER_RESOURCE_VIEWS) - { - WARN("Invalid view index %u.\n", idx); - return NULL; - } - - return device->state.shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][idx]; + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_PIXEL, idx); } void CDECL wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) @@ -2755,174 +2563,291 @@ struct wined3d_sampler * CDECL wined3d_device_get_ps_sampler(const struct wined3 { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SAMPLER_OBJECTS) - { - WARN("Invalid sampler index %u.\n", idx); - return NULL; - } - - return device->state.sampler[WINED3D_SHADER_TYPE_PIXEL][idx]; + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_PIXEL, idx); } HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device, - UINT start_register, const BOOL *constants, UINT bool_count) + unsigned int start_idx, unsigned int count, const BOOL *constants) { - UINT count = min(bool_count, MAX_CONST_B - start_register); - UINT i; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, bool_count %u.\n", - device, start_register, constants, bool_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || start_register >= MAX_CONST_B) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->ps_consts_b[start_register], constants, count * sizeof(BOOL)); - for (i = 0; i < count; ++i) - TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false"); + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + memcpy(&device->update_state->ps_consts_b[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) + { + for (i = 0; i < count; ++i) + TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); + } if (device->recording) { - for (i = start_register; i < count + start_register; ++i) + for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.pixelShaderConstantsB |= (1u << i); } else { -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, - bool_count, WINED3D_SHADER_TYPE_PIXEL); -#else /* STAGING_CSMT */ - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_B, start_idx, count, constants); } return WINED3D_OK; } HRESULT CDECL wined3d_device_get_ps_consts_b(const struct wined3d_device *device, - UINT start_register, BOOL *constants, UINT bool_count) + unsigned int start_idx, unsigned int count, BOOL *constants) { - UINT count = min(bool_count, MAX_CONST_B - start_register); + TRACE("device %p, start_idx %u, count %u,constants %p.\n", + device, start_idx, count, constants); - TRACE("device %p, start_register %u, constants %p, bool_count %u.\n", - device, start_register, constants, bool_count); - - if (!constants || start_register >= MAX_CONST_B) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_B) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.ps_consts_b[start_register], count * sizeof(BOOL)); + if (count > WINED3D_MAX_CONSTS_B - start_idx) + count = WINED3D_MAX_CONSTS_B - start_idx; + memcpy(constants, &device->state.ps_consts_b[start_idx], count * sizeof(*constants)); return WINED3D_OK; } HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device, - UINT start_register, const int *constants, UINT vector4i_count) + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants) { - UINT count = min(vector4i_count, MAX_CONST_I - start_register); - UINT i; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n", - device, start_register, constants, vector4i_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || start_register >= MAX_CONST_I) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->ps_consts_i[start_register * 4], constants, count * sizeof(int) * 4); - for (i = 0; i < count; ++i) - TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i, - constants[i * 4], constants[i * 4 + 1], - constants[i * 4 + 2], constants[i * 4 + 3]); + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + memcpy(&device->update_state->ps_consts_i[start_idx], constants, count * sizeof(*constants)); + if (TRACE_ON(d3d)) + { + for (i = 0; i < count; ++i) + TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); + } if (device->recording) { - for (i = start_register; i < count + start_register; ++i) + for (i = start_idx; i < count + start_idx; ++i) device->recording->changed.pixelShaderConstantsI |= (1u << i); } else { -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, - vector4i_count, WINED3D_SHADER_TYPE_PIXEL); -#else /* STAGING_CSMT */ - device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_I, start_idx, count, constants); } return WINED3D_OK; } HRESULT CDECL wined3d_device_get_ps_consts_i(const struct wined3d_device *device, - UINT start_register, int *constants, UINT vector4i_count) + unsigned int start_idx, unsigned int count, struct wined3d_ivec4 *constants) { - UINT count = min(vector4i_count, MAX_CONST_I - start_register); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n", - device, start_register, constants, vector4i_count); - - if (!constants || start_register >= MAX_CONST_I) + if (!constants || start_idx >= WINED3D_MAX_CONSTS_I) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.ps_consts_i[start_register * 4], count * sizeof(int) * 4); + if (count > WINED3D_MAX_CONSTS_I - start_idx) + count = WINED3D_MAX_CONSTS_I - start_idx; + memcpy(constants, &device->state.ps_consts_i[start_idx], count * sizeof(*constants)); return WINED3D_OK; } HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device, - UINT start_register, const float *constants, UINT vector4f_count) + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants) { - UINT i; const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + unsigned int i; - TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n", - device, start_register, constants, vector4f_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - /* Specifically test start_register > limit to catch MAX_UINT overflows - * when adding start_register + vector4f_count. */ - if (!constants - || start_register + vector4f_count > d3d_info->limits.ps_uniform_count - || start_register > d3d_info->limits.ps_uniform_count) + if (!constants || start_idx >= d3d_info->limits.ps_uniform_count + || count > d3d_info->limits.ps_uniform_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(&device->update_state->ps_consts_f[start_register * 4], - constants, vector4f_count * sizeof(float) * 4); + memcpy(&device->update_state->ps_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { - for (i = 0; i < vector4f_count; ++i) - TRACE("Set FLOAT constant %u to {%.8e, %.8e, %.8e, %.8e}.\n", start_register + i, - constants[i * 4], constants[i * 4 + 1], - constants[i * 4 + 2], constants[i * 4 + 3]); + for (i = 0; i < count; ++i) + TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); } if (device->recording) - memset(device->recording->changed.pixelShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count); + memset(&device->recording->changed.ps_consts_f[start_idx], 1, + count * sizeof(*device->recording->changed.ps_consts_f)); else -#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, - WINED3D_SHADER_TYPE_PIXEL); -#else /* STAGING_CSMT */ - device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count); -#endif /* STAGING_CSMT */ + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_F, start_idx, count, constants); return WINED3D_OK; } HRESULT CDECL wined3d_device_get_ps_consts_f(const struct wined3d_device *device, - UINT start_register, float *constants, UINT vector4f_count) + unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants) { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - int count = min(vector4f_count, d3d_info->limits.ps_uniform_count - start_register); - TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n", - device, start_register, constants, vector4f_count); + TRACE("device %p, start_idx %u, count %u, constants %p.\n", + device, start_idx, count, constants); - if (!constants || count < 0) + if (!constants || start_idx >= d3d_info->limits.ps_uniform_count + || count > d3d_info->limits.ps_uniform_count - start_idx) return WINED3DERR_INVALIDCALL; - memcpy(constants, &device->state.ps_consts_f[start_register * 4], count * sizeof(float) * 4); + memcpy(constants, &device->state.ps_consts_f[start_idx], count * sizeof(*constants)); return WINED3D_OK; } +void CDECL wined3d_device_set_hull_shader(struct wined3d_device *device, struct wined3d_shader *shader) +{ + struct wined3d_shader *prev; + + TRACE("device %p, shader %p.\n", device, shader); + + prev = device->update_state->shader[WINED3D_SHADER_TYPE_HULL]; + if (shader == prev) + return; + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_HULL] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_HULL, shader); + if (prev) + wined3d_shader_decref(prev); +} + +struct wined3d_shader * CDECL wined3d_device_get_hull_shader(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.shader[WINED3D_SHADER_TYPE_HULL]; +} + +void CDECL wined3d_device_set_hs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) +{ + TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); + + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_HULL, idx, buffer); +} + +struct wined3d_buffer * CDECL wined3d_device_get_hs_cb(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_HULL, idx); +} + +void CDECL wined3d_device_set_hs_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view) +{ + TRACE("device %p, idx %u, view %p.\n", device, idx, view); + + wined3d_device_set_shader_resource_view(device, WINED3D_SHADER_TYPE_HULL, idx, view); +} + +struct wined3d_shader_resource_view * CDECL wined3d_device_get_hs_resource_view(const struct wined3d_device *device, + unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_HULL, idx); +} + +void CDECL wined3d_device_set_hs_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler) +{ + TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); + + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_HULL, idx, sampler); +} + +struct wined3d_sampler * CDECL wined3d_device_get_hs_sampler(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_HULL, idx); +} + +void CDECL wined3d_device_set_domain_shader(struct wined3d_device *device, struct wined3d_shader *shader) +{ + struct wined3d_shader *prev; + + TRACE("device %p, shader %p.\n", device, shader); + + prev = device->update_state->shader[WINED3D_SHADER_TYPE_DOMAIN]; + if (shader == prev) + return; + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_DOMAIN] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_DOMAIN, shader); + if (prev) + wined3d_shader_decref(prev); +} + +struct wined3d_shader * CDECL wined3d_device_get_domain_shader(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.shader[WINED3D_SHADER_TYPE_DOMAIN]; +} + +void CDECL wined3d_device_set_ds_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) +{ + TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); + + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_DOMAIN, idx, buffer); +} + +struct wined3d_buffer * CDECL wined3d_device_get_ds_cb(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_DOMAIN, idx); +} + +void CDECL wined3d_device_set_ds_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view) +{ + TRACE("device %p, idx %u, view %p.\n", device, idx, view); + + wined3d_device_set_shader_resource_view(device, WINED3D_SHADER_TYPE_DOMAIN, idx, view); +} + +struct wined3d_shader_resource_view * CDECL wined3d_device_get_ds_resource_view(const struct wined3d_device *device, + unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_DOMAIN, idx); +} + +void CDECL wined3d_device_set_ds_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler) +{ + TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); + + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_DOMAIN, idx, sampler); +} + +struct wined3d_sampler * CDECL wined3d_device_get_ds_sampler(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_DOMAIN, idx); +} + void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) { struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; @@ -2957,13 +2882,7 @@ struct wined3d_buffer * CDECL wined3d_device_get_gs_cb(const struct wined3d_devi { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_CONSTANT_BUFFERS) - { - WARN("Invalid constant buffer index %u.\n", idx); - return NULL; - } - - return device->state.cb[WINED3D_SHADER_TYPE_GEOMETRY][idx]; + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_GEOMETRY, idx); } void CDECL wined3d_device_set_gs_resource_view(struct wined3d_device *device, @@ -2979,13 +2898,7 @@ struct wined3d_shader_resource_view * CDECL wined3d_device_get_gs_resource_view( { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SHADER_RESOURCE_VIEWS) - { - WARN("Invalid view index %u.\n", idx); - return NULL; - } - - return device->state.shader_resource_view[WINED3D_SHADER_TYPE_GEOMETRY][idx]; + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_GEOMETRY, idx); } void CDECL wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler) @@ -2999,13 +2912,144 @@ struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3 { TRACE("device %p, idx %u.\n", device, idx); - if (idx >= MAX_SAMPLER_OBJECTS) + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_GEOMETRY, idx); +} + +void CDECL wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader) +{ + struct wined3d_shader *prev; + + TRACE("device %p, shader %p.\n", device, shader); + + prev = device->update_state->shader[WINED3D_SHADER_TYPE_COMPUTE]; + if (device->recording || shader == prev) + return; + if (shader) + wined3d_shader_incref(shader); + device->update_state->shader[WINED3D_SHADER_TYPE_COMPUTE] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_COMPUTE, shader); + if (prev) + wined3d_shader_decref(prev); +} + +struct wined3d_shader * CDECL wined3d_device_get_compute_shader(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.shader[WINED3D_SHADER_TYPE_COMPUTE]; +} + +void CDECL wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer) +{ + TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer); + + wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_COMPUTE, idx, buffer); +} + +struct wined3d_buffer * CDECL wined3d_device_get_cs_cb(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_constant_buffer(device, WINED3D_SHADER_TYPE_COMPUTE, idx); +} + +void CDECL wined3d_device_set_cs_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view) +{ + TRACE("device %p, idx %u, view %p.\n", device, idx, view); + + wined3d_device_set_shader_resource_view(device, WINED3D_SHADER_TYPE_COMPUTE, idx, view); +} + +struct wined3d_shader_resource_view * CDECL wined3d_device_get_cs_resource_view(const struct wined3d_device *device, + unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_shader_resource_view(device, WINED3D_SHADER_TYPE_COMPUTE, idx); +} + +void CDECL wined3d_device_set_cs_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler) +{ + TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler); + + wined3d_device_set_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx, sampler); +} + +struct wined3d_sampler * CDECL wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_sampler(device, WINED3D_SHADER_TYPE_COMPUTE, idx); +} + +static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_device *device, + enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav) +{ + struct wined3d_unordered_access_view *prev; + + if (idx >= MAX_UNORDERED_ACCESS_VIEWS) { - WARN("Invalid sampler index %u.\n", idx); + WARN("Invalid UAV index %u.\n", idx); + return; + } + + prev = device->update_state->unordered_access_view[pipeline][idx]; + if (uav == prev) + return; + + if (uav) + wined3d_unordered_access_view_incref(uav); + device->update_state->unordered_access_view[pipeline][idx] = uav; + if (!device->recording) + wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav); + if (prev) + wined3d_unordered_access_view_decref(prev); +} + +static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unordered_access_view( + const struct wined3d_device *device, enum wined3d_pipeline pipeline, unsigned int idx) +{ + if (idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + WARN("Invalid UAV index %u.\n", idx); return NULL; } - return device->state.sampler[WINED3D_SHADER_TYPE_GEOMETRY][idx]; + return device->state.unordered_access_view[pipeline][idx]; +} + +void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx, + struct wined3d_unordered_access_view *uav) +{ + TRACE("device %p, idx %u, uav %p.\n", device, idx, uav); + + wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav); +} + +struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const struct wined3d_device *device, + unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx); +} + +void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_unordered_access_view *uav) +{ + TRACE("device %p, idx %u, uav %p.\n", device, idx, uav); + + wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav); +} + +struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access_view( + const struct wined3d_device *device, unsigned int idx) +{ + TRACE("device %p, idx %u.\n", device, idx); + + return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx); } /* Context activation is done by the caller. */ @@ -3015,6 +3059,8 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO DWORD DestFVF) { struct wined3d_matrix mat, proj_mat, view_mat, world_mat; + struct wined3d_map_desc map_desc; + struct wined3d_box box = {0}; struct wined3d_viewport vp; UINT vertex_size; unsigned int i; @@ -3055,21 +3101,15 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO doClip = FALSE; vertex_size = get_flexible_vertex_size(DestFVF); - if (FAILED(hr = wined3d_buffer_map(dest, dwDestIndex * vertex_size, dwCount * vertex_size, &dest_ptr, 0))) + box.left = dwDestIndex * vertex_size; + box.right = box.left + dwCount * vertex_size; + if (FAILED(hr = wined3d_resource_map(&dest->resource, 0, &map_desc, &box, 0))) { WARN("Failed to map buffer, hr %#x.\n", hr); return hr; } + dest_ptr = map_desc.data; -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - { - FIXME("Waiting for cs.\n"); - wined3d_cs_emit_glfinish(device->cs); - device->cs->ops->finish(device->cs); - } - -#endif /* STAGING_CSMT */ wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); @@ -3094,7 +3134,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO /* Get the viewport */ wined3d_device_get_viewport(device, &vp); - TRACE("viewport x %u, y %u, width %u, height %u, min_z %.8e, max_z %.8e.\n", + TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z); multiply_matrix(&mat,&view_mat,&world_mat); @@ -3278,7 +3318,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO } } - wined3d_buffer_unmap(dest); + wined3d_resource_unmap(&dest->resource, 0); return WINED3D_OK; } @@ -3290,8 +3330,8 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, { struct wined3d_state *state = &device->state; struct wined3d_stream_info stream_info; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_resource *resource; + struct wined3d_box box = {0}; struct wined3d_shader *vs; unsigned int i; HRESULT hr; @@ -3305,13 +3345,9 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, if (declaration) FIXME("Output vertex declaration not implemented yet.\n"); - /* Need any context to write to the vbo. */ - context = context_acquire(device, NULL); - gl_info = context->gl_info; - vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; - context_stream_info_from_declaration(context, state, &stream_info); + wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->gl_info, &device->adapter->d3d_info); state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs; /* We can't convert FROM a VBO, and vertex buffers used to source into @@ -3322,28 +3358,33 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, for (i = 0, map = stream_info.use_map; map; map >>= 1, ++i) { struct wined3d_stream_info_element *e; - struct wined3d_buffer *buffer; + struct wined3d_map_desc map_desc; if (!(map & 1)) continue; e = &stream_info.elements[i]; - buffer = state->streams[e->stream_idx].buffer; + resource = &state->streams[e->stream_idx].buffer->resource; + box.left = src_start_idx * e->stride; + box.right = box.left + vertex_count * e->stride; + if (FAILED(wined3d_resource_map(resource, 0, &map_desc, &box, WINED3D_MAP_READONLY))) + ERR("Failed to map resource.\n"); e->data.buffer_object = 0; - e->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context); - if (buffer->buffer_object) - { - GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object)); - buffer->buffer_object = 0; - } - if (e->data.addr) - e->data.addr += e->stride * src_start_idx; + e->data.addr += (ULONG_PTR)map_desc.data; } hr = process_vertices_strided(device, dst_idx, vertex_count, &stream_info, dst_buffer, flags, dst_fvf); - context_release(context); + for (i = 0, map = stream_info.use_map; map; map >>= 1, ++i) + { + if (!(map & 1)) + continue; + + resource = &state->streams[stream_info.elements[i].stream_idx].buffer->resource; + if (FAILED(wined3d_resource_unmap(resource, 0))) + ERR("Failed to unmap resource.\n"); + } return hr; } @@ -3469,6 +3510,82 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d return device->state.textures[stage]; } +void CDECL wined3d_check_device_format_support(struct wined3d_device *device, + enum wined3d_format_id check_format_id, UINT *support) +{ + const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, check_format_id, 0); + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + UINT support_flags = 0; + + if (format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_TEXTURE) + { + support_flags |= WINED3D_FORMAT_SUPPORT_BUFFER; + support_flags |= WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER; + support_flags |= WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER; + support_flags |= WINED3D_FORMAT_SUPPORT_SO_BUFFER; + } + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_1D] & WINED3DFMT_FLAG_TEXTURE) + support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE1D; + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) + { + support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE2D; + + if (gl_info->supported[EXT_TEXTURE_ARRAY]) + support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURECUBE; + + /* OpenGL requires that all officially supported formats support mip mapping */ + support_flags |= WINED3D_FORMAT_SUPPORT_MIP; + + if (support_flags & gl_info->supported[SGIS_GENERATE_MIPMAP]) + support_flags |= WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN; + + /* For the following flags it should be sufficient to check only 2d textures */ + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET) + support_flags |= WINED3D_FORMAT_SUPPORT_RENDER_TARGET; + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) + support_flags |= WINED3D_FORMAT_SUPPORT_BLENDABLE; + + if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_DEPTH) && + (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_STENCIL)) + support_flags |= WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL; + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) + support_flags |= WINED3D_FORMAT_SUPPORT_BLENDABLE; + + /* not sure how to test the following flags - assuming yes */ + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_LOAD; + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE; + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON; + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER; + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON; + + support_flags |= WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE; + support_flags |= WINED3D_FORMAT_SUPPORT_DISPLAY; + support_flags |= WINED3D_FORMAT_SUPPORT_BACK_BUFFER_CAST; + support_flags |= WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW; + support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON; + } + + if (format->flags[WINED3D_GL_RES_TYPE_TEX_3D] & WINED3DFMT_FLAG_TEXTURE) + support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE3D; + + if (gl_info->supported[ARB_MULTISAMPLE]) + { + /* TODO: check if multisampling for this format is supported */ + support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD; + support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE; + + if (support_flags & WINED3D_FORMAT_SUPPORT_RENDER_TARGET) + support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET; + } + + *support = support_flags; +} + HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps) { TRACE("device %p, caps %p.\n", device, caps); @@ -3555,10 +3672,6 @@ HRESULT CDECL wined3d_device_begin_scene(struct wined3d_device *device) HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) { -#if !defined(STAGING_CSMT) - struct wined3d_context *context; - -#endif /* STAGING_CSMT */ TRACE("device %p.\n", device); if (!device->inScene) @@ -3567,15 +3680,8 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) return WINED3DERR_INVALIDCALL; } -#if !defined(STAGING_CSMT) - context = context_acquire(device, NULL); - /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ - context->gl_info->gl_ops.gl.p_glFlush(); - /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever - * fails. */ - context_release(context); + wined3d_cs_emit_flush(device->cs); -#endif /* STAGING_CSMT */ device->inScene = FALSE; return WINED3D_OK; } @@ -3583,31 +3689,18 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { -#if defined(STAGING_CSMT) - const struct wined3d_fb_state *fb = &device->state.fb; - -#endif /* STAGING_CSMT */ - TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", - device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); + TRACE("device %p, rect_count %u, rects %p, flags %#x, color %s, depth %.8e, stencil %u.\n", + device, rect_count, rects, flags, debug_color(color), depth, stencil); if (!rect_count && rects) { WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects); return WINED3D_OK; } -#if defined(STAGING_CSMT) - if (rect_count && !rects) - rect_count = 0; - - if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - { - struct wined3d_rendertarget_view *ds = fb->depth_stencil; -#else /* STAGING_CSMT */ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) { struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; -#endif /* STAGING_CSMT */ if (!ds) { WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); @@ -3616,13 +3709,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou } else if (flags & WINED3DCLEAR_TARGET) { -#if defined(STAGING_CSMT) - if (ds->width < fb->render_targets[0]->width - || ds->height < fb->render_targets[0]->height) -#else /* STAGING_CSMT */ if (ds->width < device->fb.render_targets[0]->width || ds->height < device->fb.render_targets[0]->height) -#endif /* STAGING_CSMT */ { WARN("Silently ignoring depth and target clear with mismatching sizes\n"); return WINED3D_OK; @@ -3660,62 +3748,49 @@ struct wined3d_query * CDECL wined3d_device_get_predication(struct wined3d_devic { TRACE("device %p, value %p.\n", device, value); - *value = device->state.predicate_value; + if (value) + *value = device->state.predicate_value; return device->state.predicate; } -void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, - enum wined3d_primitive_type primitive_type) +void CDECL wined3d_device_dispatch_compute(struct wined3d_device *device, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) { - GLenum gl_primitive_type, prev; -#if !defined(STAGING_CSMT) + TRACE("device %p, group_count_x %u, group_count_y %u, group_count_z %u.\n", + device, group_count_x, group_count_y, group_count_z); -#endif /* STAGING_CSMT */ - TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type)); + wined3d_cs_emit_dispatch(device->cs, group_count_x, group_count_y, group_count_z); +} - gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); - prev = device->update_state->gl_primitive_type; - device->update_state->gl_primitive_type = gl_primitive_type; - if (device->recording) - device->recording->changed.primitive_type = TRUE; -#if defined(STAGING_CSMT) - else if (gl_primitive_type != prev) - wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); -#else /* STAGING_CSMT */ - else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) - device_invalidate_state(device, STATE_POINT_ENABLE); -#endif /* STAGING_CSMT */ +void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, + enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count) +{ + TRACE("device %p, primitive_type %s, patch_vertex_count %u.\n", + device, debug_d3dprimitivetype(primitive_type), patch_vertex_count); + + device->state.gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); + device->state.gl_patch_vertices = patch_vertex_count; } void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, - enum wined3d_primitive_type *primitive_type) + enum wined3d_primitive_type *primitive_type, unsigned int *patch_vertex_count) { - TRACE("device %p, primitive_type %p\n", device, primitive_type); + TRACE("device %p, primitive_type %p, patch_vertex_count %p.\n", + device, primitive_type, patch_vertex_count); *primitive_type = d3d_primitive_type_from_gl(device->state.gl_primitive_type); + if (patch_vertex_count) + *patch_vertex_count = device->state.gl_patch_vertices; - TRACE("Returning %s\n", debug_d3dprimitivetype(*primitive_type)); + TRACE("Returning %s.\n", debug_d3dprimitivetype(*primitive_type)); } HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count) { TRACE("device %p, start_vertex %u, vertex_count %u.\n", device, start_vertex, vertex_count); - if (!device->state.vertex_declaration) - { - WARN("Called without a valid vertex declaration set.\n"); - return WINED3DERR_INVALIDCALL; - } - -#if !defined(STAGING_CSMT) - if (device->state.load_base_vertex_index) - { - device->state.load_base_vertex_index = 0; - device_invalidate_state(device, STATE_BASEVERTEXINDEX); - } - -#endif /* STAGING_CSMT */ - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); + wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices, + 0, start_vertex, vertex_count, 0, 0, FALSE); return WINED3D_OK; } @@ -3726,15 +3801,12 @@ void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device TRACE("device %p, start_vertex %u, vertex_count %u, start_instance %u, instance_count %u.\n", device, start_vertex, vertex_count, start_instance, instance_count); - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, start_instance, instance_count, FALSE); + wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices, + 0, start_vertex, vertex_count, start_instance, instance_count, FALSE); } HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) { -#if !defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - -#endif /* STAGING_CSMT */ TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); if (!device->state.index_buffer) @@ -3747,22 +3819,8 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic return WINED3DERR_INVALIDCALL; } - if (!device->state.vertex_declaration) - { - WARN("Called without a valid vertex declaration set.\n"); - return WINED3DERR_INVALIDCALL; - } - -#if !defined(STAGING_CSMT) - if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && - device->state.load_base_vertex_index != device->state.base_vertex_index) - { - device->state.load_base_vertex_index = device->state.base_vertex_index; - device_invalidate_state(device, STATE_BASEVERTEXINDEX); - } - -#endif /* STAGING_CSMT */ - wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); + wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices, + device->state.base_vertex_index, start_idx, index_count, 0, 0, TRUE); return WINED3D_OK; } @@ -3773,104 +3831,19 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", device, start_idx, index_count, start_instance, instance_count); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); -} - -/* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ -#if defined(STAGING_CSMT) -static void device_update_volume(struct wined3d_context *context, - struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) -{ - struct wined3d_bo_address data; - - TRACE("src_volume %p, dst_volume %p.\n", - src_volume, dst_volume); - - if (src_volume->resource.format != dst_volume->resource.format) - { - FIXME("Source and destination formats do not match.\n"); - return; - } - if (src_volume->resource.width != dst_volume->resource.width - || src_volume->resource.height != dst_volume->resource.height - || src_volume->resource.depth != dst_volume->resource.depth) - { - FIXME("Source and destination sizes do not match.\n"); - return; - } - - /* Only a prepare, since we're uploading the entire volume. */ - wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); - wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); - - wined3d_resource_get_memory(&src_volume->resource, src_volume->resource.map_binding, &data); - wined3d_volume_upload_data(dst_volume, context, wined3d_const_bo_address(&data)); - wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -} - -/* Context activation is done by the caller */ -void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, - struct wined3d_texture *dst_texture) -{ - unsigned int src_size, dst_size, src_skip_levels = 0; - unsigned int layer_count, level_count, i, j; - enum wined3d_resource_type type = src_texture->resource.type; - - layer_count = src_texture->layer_count; -#else /* STAGING_CSMT */ -static HRESULT device_update_volume(struct wined3d_device *device, - struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) -{ - struct wined3d_const_bo_address data; - struct wined3d_map_desc src; - HRESULT hr; - struct wined3d_context *context; - - TRACE("device %p, src_volume %p, dst_volume %p.\n", - device, src_volume, dst_volume); - - if (src_volume->resource.format != dst_volume->resource.format) - { - FIXME("Source and destination formats do not match.\n"); - return WINED3DERR_INVALIDCALL; - } - if (src_volume->resource.width != dst_volume->resource.width - || src_volume->resource.height != dst_volume->resource.height - || src_volume->resource.depth != dst_volume->resource.depth) - { - FIXME("Source and destination sizes do not match.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) - return hr; - - context = context_acquire(device, NULL); - - /* Only a prepare, since we're uploading the entire volume. */ - wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); - wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); - - data.buffer_object = 0; - data.addr = src.data; - wined3d_volume_upload_data(dst_volume, context, &data); - wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB); - - context_release(context); - - hr = wined3d_volume_unmap(src_volume); - - return hr; + wined3d_cs_emit_draw(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices, + device->state.base_vertex_index, start_idx, index_count, start_instance, instance_count, TRUE); } HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) { unsigned int src_size, dst_size, src_skip_levels = 0; + unsigned int src_level_count, dst_level_count; unsigned int layer_count, level_count, i, j; + unsigned int width, height, depth; enum wined3d_resource_type type; - HRESULT hr; - struct wined3d_context *context; + struct wined3d_box box; TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); @@ -3907,13 +3880,19 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; } -#endif /* STAGING_CSMT */ - level_count = min(wined3d_texture_get_level_count(src_texture), - wined3d_texture_get_level_count(dst_texture)); + if (src_texture->resource.format != dst_texture->resource.format) + { + WARN("Source and destination formats do not match.\n"); + return WINED3DERR_INVALIDCALL; + } + + src_level_count = src_texture->level_count; + dst_level_count = dst_texture->level_count; + level_count = min(src_level_count, dst_level_count); src_size = max(src_texture->resource.width, src_texture->resource.height); dst_size = max(dst_texture->resource.width, dst_texture->resource.height); - if (type == WINED3D_RTYPE_VOLUME) + if (type == WINED3D_RTYPE_TEXTURE_3D) { src_size = max(src_size, src_texture->resource.depth); dst_size = max(dst_size, dst_texture->resource.depth); @@ -3924,132 +3903,30 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, ++src_skip_levels; } - /* Make sure that the destination texture is loaded. */ -#if defined(STAGING_CSMT) - wined3d_texture_load(dst_texture, context, FALSE); -#else /* STAGING_CSMT */ - context = context_acquire(device, NULL); - wined3d_texture_load(dst_texture, context, FALSE); - context_release(context); -#endif /* STAGING_CSMT */ + if (wined3d_texture_get_level_width(src_texture, src_skip_levels) != dst_texture->resource.width + || wined3d_texture_get_level_height(src_texture, src_skip_levels) != dst_texture->resource.height + || wined3d_texture_get_level_depth(src_texture, src_skip_levels) != dst_texture->resource.depth) + { + WARN("Source and destination dimensions do not match.\n"); + return WINED3DERR_INVALIDCALL; + } /* Update every surface level of the texture. */ - switch (type) + for (i = 0; i < level_count; ++i) { - case WINED3D_RTYPE_TEXTURE_2D: + width = wined3d_texture_get_level_width(dst_texture, i); + height = wined3d_texture_get_level_height(dst_texture, i); + depth = wined3d_texture_get_level_depth(dst_texture, i); + wined3d_box_set(&box, 0, 0, width, height, 0, depth); + + for (j = 0; j < layer_count; ++j) { - unsigned int src_levels = src_texture->level_count; - unsigned int dst_levels = dst_texture->level_count; - struct wined3d_surface *src_surface; - struct wined3d_surface *dst_surface; - - for (i = 0; i < layer_count; ++i) - { - for (j = 0; j < level_count; ++j) - { - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, - i * src_levels + j + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, - i * dst_levels + j)); -#if defined(STAGING_CSMT) - surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); -#else /* STAGING_CSMT */ - if (FAILED(hr = surface_upload_from_surface(dst_surface, NULL, src_surface, NULL))) - { - WARN("Failed to update surface, hr %#x.\n", hr); - return hr; - } -#endif /* STAGING_CSMT */ - } - } - break; + wined3d_cs_emit_blt_sub_resource(device->cs, + &dst_texture->resource, j * dst_level_count + i, &box, + &src_texture->resource, j * src_level_count + i + src_skip_levels, &box, + 0, NULL, WINED3D_TEXF_POINT); } - - case WINED3D_RTYPE_TEXTURE_3D: - { - for (i = 0; i < level_count; ++i) - { -#if defined(STAGING_CSMT) - device_update_volume(context, - volume_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)), - volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); - } - break; - } - - default: - FIXME("Unsupported texture type %#x.\n", type); - return; } -} - -HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) -{ - enum wined3d_resource_type type; - unsigned int layer_count; - - TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); - - /* Verify that the source and destination textures are non-NULL. */ - if (!src_texture || !dst_texture) - { - WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) - { - WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) - { - WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - if (dst_texture->resource.format != src_texture->resource.format) - { - WARN("Formats do not match, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - /* Verify that the source and destination textures are the same type. */ - type = src_texture->resource.type; - if (dst_texture->resource.type != type) - { - WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - layer_count = src_texture->layer_count; - if (layer_count != dst_texture->layer_count) - { - WARN("Source and destination have different layer counts.\n"); - return WINED3DERR_INVALIDCALL; - } - - wined3d_cs_emit_update_texture(device->cs, src_texture, dst_texture); -#else /* STAGING_CSMT */ - hr = device_update_volume(device, - volume_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)), - volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); - if (FAILED(hr)) - { - WARN("Failed to update volume, hr %#x.\n", hr); - return hr; - } - } - break; - } - - default: - FIXME("Unsupported texture type %#x.\n", type); - return WINED3DERR_INVALIDCALL; - } -#endif /* STAGING_CSMT */ return WINED3D_OK; } @@ -4099,13 +3976,8 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_STENCILENABLE]) { -#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *rt = state->fb.render_targets[0]; - struct wined3d_rendertarget_view *ds = state->fb.depth_stencil; -#else /* STAGING_CSMT */ struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; -#endif /* STAGING_CSMT */ if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) { @@ -4201,11 +4073,9 @@ float CDECL wined3d_device_get_npatch_mode(const struct wined3d_device *device) void CDECL wined3d_device_copy_resource(struct wined3d_device *device, struct wined3d_resource *dst_resource, struct wined3d_resource *src_resource) { - struct wined3d_surface *dst_surface, *src_surface; struct wined3d_texture *dst_texture, *src_texture; - RECT dst_rect, src_rect; - unsigned int i, count; - HRESULT hr; + struct wined3d_box box; + unsigned int i, j; TRACE("device %p, dst_resource %p, src_resource %p.\n", device, dst_resource, src_resource); @@ -4241,14 +4111,16 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, return; } - if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (dst_resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); + wined3d_box_set(&box, 0, 0, src_resource->size, 1, 0, 1); + wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &box, + src_resource, 0, &box, 0, NULL, WINED3D_TEXF_POINT); return; } - dst_texture = wined3d_texture_from_resource(dst_resource); - src_texture = wined3d_texture_from_resource(src_resource); + dst_texture = texture_from_resource(dst_resource); + src_texture = texture_from_resource(src_resource); if (src_texture->layer_count != dst_texture->layer_count || src_texture->level_count != dst_texture->level_count) @@ -4259,17 +4131,19 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device, return; } - count = dst_texture->layer_count * dst_texture->level_count; - for (i = 0; i < count; ++i) + for (i = 0; i < dst_texture->level_count; ++i) { - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)); - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, i)); + wined3d_box_set(&box, 0, 0, + wined3d_texture_get_level_width(dst_texture, i), + wined3d_texture_get_level_height(dst_texture, i), + 0, wined3d_texture_get_level_depth(dst_texture, i)); + for (j = 0; j < dst_texture->layer_count; ++j) + { + unsigned int idx = j * dst_texture->level_count + i; - SetRect(&dst_rect, 0, 0, dst_surface->resource.width, dst_surface->resource.height); - SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height); - if (FAILED(hr = wined3d_surface_blt(dst_surface, &dst_rect, - src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) - ERR("Failed to blit, sub-resource %u, hr %#x.\n", i, hr); + wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &box, + src_resource, idx, &box, 0, NULL, WINED3D_TEXF_POINT); + } } } @@ -4278,11 +4152,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) { - struct wined3d_surface *dst_surface, *src_surface; - struct wined3d_texture *dst_texture, *src_texture; - struct wined3d_resource *tmp; - RECT dst_rect, src_rect; - HRESULT hr; + struct wined3d_box dst_box, b; TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " "src_resource %p, src_sub_resource_idx %u, src_box %s.\n", @@ -4311,177 +4181,193 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } - if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (dst_resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); - return WINED3DERR_INVALIDCALL; - } + if (dst_sub_resource_idx) + { + WARN("Invalid dst_sub_resource_idx %u.\n", dst_sub_resource_idx); + return WINED3DERR_INVALIDCALL; + } - dst_texture = wined3d_texture_from_resource(dst_resource); - if (!(tmp = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx))) - { - WARN("Invalid dst_sub_resource_idx %u.\n", dst_sub_resource_idx); - return WINED3DERR_INVALIDCALL; - } - dst_surface = surface_from_resource(tmp); + if (src_sub_resource_idx) + { + WARN("Invalid src_sub_resource_idx %u.\n", src_sub_resource_idx); + return WINED3DERR_INVALIDCALL; + } - src_texture = wined3d_texture_from_resource(src_resource); - if (!(tmp = wined3d_texture_get_sub_resource(src_texture, src_sub_resource_idx))) - { - WARN("Invalid src_sub_resource_idx %u.\n", src_sub_resource_idx); - return WINED3DERR_INVALIDCALL; - } - src_surface = surface_from_resource(tmp); - - if (src_box) - { - if (src_box->front >= src_box->back) + if (!src_box) + { + wined3d_box_set(&b, 0, 0, src_resource->size, 1, 0, 1); + src_box = &b; + } + else if ((src_box->left >= src_box->right + || src_box->top >= src_box->bottom + || src_box->front >= src_box->back)) { WARN("Invalid box %s specified.\n", debug_box(src_box)); return WINED3DERR_INVALIDCALL; } - src_rect.left = src_box->left; - src_rect.top = src_box->top; - src_rect.right = src_box->right; - src_rect.bottom = src_box->bottom; + if (src_box->right > src_resource->size || dst_x >= dst_resource->size + || src_box->right - src_box->left > dst_resource->size - dst_x) + { + WARN("Invalid range specified, dst_offset %u, src_offset %u, size %u.\n", + dst_x, src_box->left, src_box->right - src_box->left); + return WINED3DERR_INVALIDCALL; + } + + wined3d_box_set(&dst_box, dst_x, 0, dst_x + (src_box->right - src_box->left), 1, 0, 1); + } + else if (dst_resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_texture *dst_texture = texture_from_resource(dst_resource); + struct wined3d_texture *src_texture = texture_from_resource(src_resource); + unsigned int src_level = src_sub_resource_idx % src_texture->level_count; + + if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count) + { + WARN("Invalid destination sub-resource %u.\n", dst_sub_resource_idx); + return WINED3DERR_INVALIDCALL; + } + + if (src_sub_resource_idx >= src_texture->level_count * src_texture->layer_count) + { + WARN("Invalid source sub-resource %u.\n", src_sub_resource_idx); + return WINED3DERR_INVALIDCALL; + } + +#if !defined(STAGING_CSMT) + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count) + { + WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx); + return WINED3DERR_INVALIDCALL; + } + + if (src_texture->sub_resources[src_sub_resource_idx].map_count) + { + WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx); + return WINED3DERR_INVALIDCALL; +#else /* STAGING_CSMT */ + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || + src_texture->sub_resources[src_sub_resource_idx].map_count) + { + struct wined3d_device *device = dst_texture->resource.device; + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count || + src_texture->sub_resources[src_sub_resource_idx].map_count) + { + WARN("Destination or source sub-resource is mapped.\n"); + return WINEDDERR_SURFACEBUSY; + } +#endif /* STAGING_CSMT */ + } + + if (!src_box) + { + wined3d_box_set(&b, 0, 0, wined3d_texture_get_level_width(src_texture, src_level), + wined3d_texture_get_level_height(src_texture, src_level), 0, 1); + src_box = &b; + } + else if (FAILED(wined3d_texture_check_box_dimensions(src_texture, src_level, src_box))) + { + WARN("Invalid source box %s.\n", debug_box(src_box)); + return WINED3DERR_INVALIDCALL; + } + + wined3d_box_set(&dst_box, dst_x, dst_y, dst_x + (src_box->right - src_box->left), + dst_y + (src_box->bottom - src_box->top), 0, 1); + if (FAILED(wined3d_texture_check_box_dimensions(dst_texture, + dst_sub_resource_idx % dst_texture->level_count, &dst_box))) + { + WARN("Invalid destination box %s.\n", debug_box(&dst_box)); + return WINED3DERR_INVALIDCALL; + } } else { - src_rect.left = 0; - src_rect.top = 0; - src_rect.right = src_surface->resource.width; - src_rect.bottom = src_surface->resource.height; + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); + return WINED3DERR_INVALIDCALL; } - dst_rect.left = dst_x; - dst_rect.top = dst_y; - dst_rect.right = dst_x + (src_rect.right - src_rect.left); - dst_rect.bottom = dst_y + (src_rect.bottom - src_rect.top); + wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box, + src_resource, src_sub_resource_idx, src_box, 0, NULL, WINED3D_TEXF_POINT); - if (FAILED(hr = wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) - WARN("Failed to blit, hr %#x.\n", hr); - - return hr; + return WINED3D_OK; } void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, unsigned int depth_pitch) { - struct wined3d_resource *sub_resource; -#if defined(STAGING_CSMT) - struct wined3d_texture *texture; -#else /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info; - struct wined3d_const_bo_address addr; - struct wined3d_context *context; - struct wined3d_texture *texture; - struct wined3d_surface *surface; - POINT dst_point; - RECT src_rect; -#endif /* STAGING_CSMT */ + unsigned int width, height, depth; + struct wined3d_box b; TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); if (resource->type == WINED3D_RTYPE_BUFFER) { - struct wined3d_buffer *buffer = buffer_from_resource(resource); - HRESULT hr; - if (sub_resource_idx > 0) { WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); return; } - if (FAILED(hr = wined3d_buffer_upload_data(buffer, box, data))) - WARN("Failed to update buffer data, hr %#x.\n", hr); - - return; + width = resource->size; + height = 1; + depth = 1; } + else if (resource->type == WINED3D_RTYPE_TEXTURE_1D || + resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D) + { + struct wined3d_texture *texture = texture_from_resource(resource); + unsigned int level; - if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + if (sub_resource_idx >= texture->level_count * texture->layer_count) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return; + } + + level = sub_resource_idx % texture->level_count; + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + depth = wined3d_texture_get_level_depth(texture, level); + } + else { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); return; } - texture = wined3d_texture_from_resource(resource); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) + if (!box) { - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return; + wined3d_box_set(&b, 0, 0, width, height, 0, depth); + box = &b; } -#if defined(STAGING_CSMT) - -#else /* STAGING_CSMT */ - surface = surface_from_resource(sub_resource); - - src_rect.left = 0; - src_rect.top = 0; -#endif /* STAGING_CSMT */ - if (box) + else if (box->left >= box->right || box->right > width + || box->top >= box->bottom || box->bottom > height + || box->front >= box->back || box->back > depth) { - if (box->left >= box->right || box->right > sub_resource->width - || box->top >= box->bottom || box->bottom > sub_resource->height - || box->front >= box->back) - { - WARN("Invalid box %s specified.\n", debug_box(box)); - return; - } -#if defined(STAGING_CSMT) + WARN("Invalid box %s specified.\n", debug_box(box)); + return; } wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); -#else /* STAGING_CSMT */ - - src_rect.right = box->right - box->left; - src_rect.bottom = box->bottom - box->top; - dst_point.x = box->left; - dst_point.y = box->top; - } - else - { - src_rect.right = sub_resource->width; - src_rect.bottom = sub_resource->height; - dst_point.x = 0; - dst_point.y = 0; - } - - addr.buffer_object = 0; - addr.addr = data; - - context = context_acquire(resource->device, NULL); - gl_info = context->gl_info; - - /* Only load the surface for partial updates. */ - if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width - && src_rect.bottom == sub_resource->height) - wined3d_texture_prepare_texture(texture, context, FALSE); - else - surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - - wined3d_surface_upload_data(surface, gl_info, resource->format, - &src_rect, row_pitch, &dst_point, FALSE, &addr); - - context_release(context); - - surface_validate_location(surface, WINED3D_LOCATION_TEXTURE_RGB); - surface_invalidate_location(surface, ~WINED3D_LOCATION_TEXTURE_RGB); -#endif /* STAGING_CSMT */ } HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, - struct wined3d_rendertarget_view *view, const RECT *rect, const struct wined3d_color *color) + struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags, + const struct wined3d_color *color, float depth, DWORD stencil) { struct wined3d_resource *resource; RECT r; - TRACE("device %p, view %p, rect %s, color {%.8e, %.8e, %.8e, %.8e}.\n", - device, view, wine_dbgstr_rect(rect), color->r, color->g, color->b, color->a); + TRACE("device %p, view %p, rect %s, flags %#x, color %s, depth %.8e, stencil %u.\n", + device, view, wine_dbgstr_rect(rect), flags, debug_color(color), depth, stencil); + + if (!flags) + return WINED3D_OK; resource = view->resource; if (resource->type != WINED3D_RTYPE_TEXTURE_2D) @@ -4490,7 +4376,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi return WINED3DERR_INVALIDCALL; } - if (view->depth > 1) + if (view->layer_count > 1) { FIXME("Layered clears not implemented.\n"); return WINED3DERR_INVALIDCALL; @@ -4501,15 +4387,28 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi SetRect(&r, 0, 0, view->width, view->height); rect = &r; } + else + { + struct wined3d_box b = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; + struct wined3d_texture *texture = texture_from_resource(view->resource); + HRESULT hr; + + if (FAILED(hr = wined3d_texture_check_box_dimensions(texture, + view->sub_resource_idx % texture->level_count, &b))) + return hr; + } + + wined3d_cs_emit_clear_rendertarget_view(device->cs, view, rect, flags, color, depth, stencil); -#if defined(STAGING_CSMT) - wined3d_cs_emit_clear_rtv(device->cs, view, rect, color); return WINED3D_OK; -#else /* STAGING_CSMT */ - resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); +} - return surface_color_fill(surface_from_resource(resource), rect, color); -#endif /* STAGING_CSMT */ +void CDECL wined3d_device_clear_unordered_access_view_uint(struct wined3d_device *device, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) +{ + TRACE("device %p, view %p, clear_value %s.\n", device, view, debug_uvec4(clear_value)); + + wined3d_cs_emit_clear_unordered_access_view_uint(device->cs, view, clear_value); } struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, @@ -4523,23 +4422,6 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(co return NULL; } -#if defined(STAGING_CSMT) - return device->state.fb.render_targets[view_idx]; -} - -struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) -{ - TRACE("device %p.\n", device); - - return device->state.fb.depth_stencil; -} - -HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) -{ - struct wined3d_rendertarget_view *prev; - struct wined3d_fb_state *fb = &device->state.fb; -#else /* STAGING_CSMT */ return device->fb.render_targets[view_idx]; } @@ -4554,7 +4436,6 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) { struct wined3d_rendertarget_view *prev; -#endif /* STAGING_CSMT */ TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", device, view_idx, view, set_viewport); @@ -4586,23 +4467,11 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device state->viewport.max_z = 1.0f; wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - state->scissor_rect.top = 0; - state->scissor_rect.left = 0; - state->scissor_rect.right = view->width; - state->scissor_rect.bottom = view->height; + SetRect(&state->scissor_rect, 0, 0, view->width, view->height); wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } -#if defined(STAGING_CSMT) - prev = fb->render_targets[view_idx]; - if (view == prev) - return WINED3D_OK; - - if (view) - wined3d_rendertarget_view_incref(view); - fb->render_targets[view_idx] = view; -#else /* STAGING_CSMT */ prev = device->fb.render_targets[view_idx]; if (view == prev) return WINED3D_OK; @@ -4610,7 +4479,6 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device if (view) wined3d_rendertarget_view_incref(view); device->fb.render_targets[view_idx] = view; -#endif /* STAGING_CSMT */ wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); /* Release after the assignment, to prevent device_resource_released() * from seeing the surface as still in use. */ @@ -4622,25 +4490,6 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) { -#if defined(STAGING_CSMT) - struct wined3d_fb_state *fb = &device->state.fb; - struct wined3d_rendertarget_view *prev; - - TRACE("device %p, view %p.\n", device, view); - - prev = fb->depth_stencil; - if (prev == view) - { - TRACE("Trying to do a NOP SetRenderTarget operation.\n"); - return; - } - - if ((fb->depth_stencil = view)) - wined3d_rendertarget_view_incref(view); - wined3d_cs_emit_set_depth_stencil_view(device->cs, view); - if (prev) - wined3d_rendertarget_view_decref(prev); -#else /* STAGING_CSMT */ struct wined3d_rendertarget_view *prev; TRACE("device %p, view %p.\n", device, view); @@ -4660,17 +4509,18 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, } static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, - struct wined3d_surface *cursor_image) + struct wined3d_texture *cursor_image, unsigned int sub_resource_idx) { + unsigned int texture_level = sub_resource_idx % cursor_image->level_count; struct wined3d_sub_resource_data data; struct wined3d_resource_desc desc; struct wined3d_map_desc map_desc; struct wined3d_texture *texture; HRESULT hr; - if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) + if (FAILED(wined3d_resource_map(&cursor_image->resource, sub_resource_idx, &map_desc, NULL, WINED3D_MAP_READONLY))) { - ERR("Failed to map source surface.\n"); + ERR("Failed to map source texture.\n"); return NULL; } @@ -4684,14 +4534,14 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined desc.multisample_quality = 0; desc.usage = WINED3DUSAGE_DYNAMIC; desc.pool = WINED3D_POOL_DEFAULT; - desc.width = cursor_image->resource.width; - desc.height = cursor_image->resource.height; + desc.width = wined3d_texture_get_level_width(cursor_image, texture_level); + desc.height = wined3d_texture_get_level_height(cursor_image, texture_level); desc.depth = 1; desc.size = 0; - hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, + hr = wined3d_texture_create(device, &desc, 1, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, &data, NULL, &wined3d_null_parent_ops, &texture); - wined3d_surface_unmap(cursor_image); + wined3d_resource_unmap(&cursor_image->resource, sub_resource_idx); if (FAILED(hr)) { ERR("Failed to create cursor texture.\n"); @@ -4699,39 +4549,34 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined } return texture; -#endif /* STAGING_CSMT */ } HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx) { + unsigned int texture_level = sub_resource_idx % texture->level_count; + unsigned int cursor_width, cursor_height; struct wined3d_display_mode mode; struct wined3d_map_desc map_desc; - struct wined3d_resource *sub_resource; - struct wined3d_surface *cursor_image; HRESULT hr; TRACE("device %p, x_hotspot %u, y_hotspot %u, texture %p, sub_resource_idx %u.\n", device, x_hotspot, y_hotspot, texture, sub_resource_idx); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)) - || sub_resource->type != WINED3D_RTYPE_SURFACE) + if (sub_resource_idx >= texture->level_count * texture->layer_count + || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) return WINED3DERR_INVALIDCALL; - cursor_image = surface_from_resource(sub_resource); - -#if !defined(STAGING_CSMT) if (device->cursor_texture) { wined3d_texture_decref(device->cursor_texture); device->cursor_texture = NULL; } -#endif /* STAGING_CSMT */ - if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) + if (texture->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) { - WARN("Surface %p has an invalid format %s.\n", - cursor_image, debug_d3dformat(cursor_image->resource.format->id)); + WARN("Texture %p has invalid format %s.\n", + texture, debug_d3dformat(texture->resource.format->id)); return WINED3DERR_INVALIDCALL; } @@ -4741,11 +4586,12 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device return WINED3DERR_INVALIDCALL; } - if (cursor_image->resource.width > mode.width || cursor_image->resource.height > mode.height) + cursor_width = wined3d_texture_get_level_width(texture, texture_level); + cursor_height = wined3d_texture_get_level_height(texture, texture_level); + if (cursor_width > mode.width || cursor_height > mode.height) { - WARN("Surface %p dimensions are %ux%u, but screen dimensions are %ux%u.\n", - cursor_image, cursor_image->resource.width, cursor_image->resource.height, - mode.width, mode.height); + WARN("Texture %p, sub-resource %u dimensions are %ux%u, but screen dimensions are %ux%u.\n", + texture, sub_resource_idx, cursor_width, cursor_height, mode.width, mode.height); return WINED3DERR_INVALIDCALL; } @@ -4755,17 +4601,15 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device * release it after setting the cursor image. Windows doesn't * addref the set surface, so we can't do this either without * creating circular refcount dependencies. */ -#if !defined(STAGING_CSMT) - if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) + if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, texture, sub_resource_idx))) { ERR("Failed to create cursor texture.\n"); return WINED3DERR_INVALIDCALL; } -#endif /* STAGING_CSMT */ - if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) + if (cursor_width == 32 && cursor_height == 32) { - UINT mask_size = cursor_image->resource.width * cursor_image->resource.height / 8; + UINT mask_size = cursor_width * cursor_height / 8; ICONINFO cursor_info; DWORD *mask_bits; HCURSOR cursor; @@ -4777,15 +4621,14 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device return E_OUTOFMEMORY; memset(mask_bits, 0xff, mask_size); - wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY); + wined3d_resource_map(&texture->resource, sub_resource_idx, &map_desc, NULL, + WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY); cursor_info.fIcon = FALSE; cursor_info.xHotspot = x_hotspot; cursor_info.yHotspot = y_hotspot; - cursor_info.hbmMask = CreateBitmap(cursor_image->resource.width, - cursor_image->resource.height, 1, 1, mask_bits); - cursor_info.hbmColor = CreateBitmap(cursor_image->resource.width, - cursor_image->resource.height, 1, 32, map_desc.data); - wined3d_surface_unmap(cursor_image); + cursor_info.hbmMask = CreateBitmap(cursor_width, cursor_height, 1, 1, mask_bits); + cursor_info.hbmColor = CreateBitmap(cursor_width, cursor_height, 1, 32, map_desc.data); + wined3d_resource_unmap(&texture->resource, sub_resource_idx); /* Create our cursor and clean up. */ cursor = CreateIconIndirect(&cursor_info); @@ -4802,9 +4645,9 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device HeapFree(GetProcessHeap(), 0, mask_bits); } - TRACE("New cursor dimensions are %ux%u.\n", cursor_image->resource.width, cursor_image->resource.height); - device->cursorWidth = cursor_image->resource.width; - device->cursorHeight = cursor_image->resource.height; + TRACE("New cursor dimensions are %ux%u.\n", cursor_width, cursor_height); + device->cursorWidth = cursor_width; + device->cursorHeight = cursor_height; device->xHotSpot = x_hotspot; device->yHotSpot = y_hotspot; @@ -4866,12 +4709,10 @@ BOOL CDECL wined3d_device_show_cursor(struct wined3d_device *device, BOOL show) else SetCursor(NULL); } -#if !defined(STAGING_CSMT) else if (device->cursor_texture) { device->bCursorVisible = show; } -#endif /* STAGING_CSMT */ return oldVisible; } @@ -4882,10 +4723,6 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) TRACE("device %p.\n", device); -#if defined(STAGING_CSMT) - /* The resource list is manged by the main thread, iterate here and emit commands for - * each resource */ -#endif /* STAGING_CSMT */ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) { TRACE("Checking resource %p for eviction.\n", resource); @@ -4893,191 +4730,32 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count) { TRACE("Evicting %p.\n", resource); -#if defined(STAGING_CSMT) - wined3d_cs_emit_evict_resource(device->cs, resource); + wined3d_cs_emit_unload_resource(device->cs, resource); } } } -void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -{ - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_shader *shader; - - LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) - { - device->shader_backend->shader_destroy(shader); - } - - context = context_acquire(device, NULL); - gl_info = context->gl_info; -#else /* STAGING_CSMT */ - resource->resource_ops->resource_unload(resource); - } - } - - /* Invalidate stream sources, the buffer(s) may have been evicted. */ - device_invalidate_state(device, STATE_STREAMSRC); -} - -static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -{ - struct wined3d_resource *resource, *cursor; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_shader *shader; - - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - - resource->resource_ops->resource_unload(resource); - } - - LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) - { - device->shader_backend->shader_destroy(shader); - } -#endif /* STAGING_CSMT */ - - if (device->depth_blt_texture) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); - device->depth_blt_texture = 0; - } - - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); - destroy_default_sampler(device); - - context_release(context); - - while (device->context_count) - { - swapchain_destroy_contexts(device->contexts[0]->swapchain); - } - - HeapFree(GetProcessHeap(), 0, swapchain->context); - swapchain->context = NULL; -#if defined(STAGING_CSMT) - swapchain->num_contexts = 0; -} - -static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -{ - struct wined3d_resource *resource, *cursor; - - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - - wined3d_cs_emit_evict_resource(device->cs, resource); - } - - wined3d_cs_emit_delete_opengl_contexts(device->cs, swapchain); -} - -static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -{ -#else /* STAGING_CSMT */ -} - -static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -{ - struct wined3d_context *context; - struct wined3d_surface *target; -#endif /* STAGING_CSMT */ - HRESULT hr; - - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, - device->adapter->vertex_pipe, device->adapter->fragment_pipe))) - { - ERR("Failed to allocate shader private data, hr %#x.\n", hr); - return hr; - } - - if (FAILED(hr = device->blitter->alloc_private(device))) - { - ERR("Failed to allocate blitter private data, hr %#x.\n", hr); - device->shader_backend->shader_free_private(device); - return hr; - } - -#if defined(STAGING_CSMT) - hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); - if (FAILED(hr)) - { - WARN("Failed to create context.\n"); - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); - return hr; - } - - wined3d_cs_emit_create_dummy_textures(device->cs); -#else /* STAGING_CSMT */ - /* Recreate the primary swapchain's context */ - swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); - if (!swapchain->context) - { - ERR("Failed to allocate memory for swapchain context array.\n"); - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); - return E_OUTOFMEMORY; - } - - target = swapchain->back_buffers - ? surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)) - : surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - if (!(context = context_create(swapchain, target, swapchain->ds_format))) - { - WARN("Failed to create context.\n"); - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); - HeapFree(GetProcessHeap(), 0, swapchain->context); - return E_FAIL; - } - - swapchain->context[0] = context; - swapchain->num_contexts = 1; - create_dummy_textures(device, context); - create_default_sampler(device); - context_release(context); -#endif /* STAGING_CSMT */ - - return WINED3D_OK; -} - HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state) { - struct wined3d_rendertarget_view_desc view_desc; struct wined3d_resource *resource, *cursor; struct wined3d_swapchain *swapchain; - struct wined3d_display_mode m; - BOOL DisplayModeChanged; + struct wined3d_view_desc view_desc; + BOOL backbuffer_resized; HRESULT hr = WINED3D_OK; unsigned int i; TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", device, swapchain_desc, mode, callback, reset_state); -#if defined(STAGING_CSMT) - wined3d_cs_emit_glfinish(device->cs); - device->cs->ops->finish(device->cs); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); -#endif /* STAGING_CSMT */ if (!(swapchain = wined3d_device_get_swapchain(device, 0))) { ERR("Failed to get the first implicit swapchain.\n"); return WINED3DERR_INVALIDCALL; } - DisplayModeChanged = swapchain->reapply_mode; if (reset_state) { @@ -5086,11 +4764,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_texture_decref(device->logo_texture); device->logo_texture = NULL; } -#if defined(STAGING_CSMT) - } - - if (device->state.fb.render_targets) -#else /* STAGING_CSMT */ if (device->cursor_texture) { wined3d_texture_decref(device->cursor_texture); @@ -5100,7 +4773,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } if (device->fb.render_targets) -#endif /* STAGING_CSMT */ { for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) { @@ -5109,24 +4781,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } wined3d_device_set_depth_stencil_view(device, NULL); -#if defined(STAGING_CSMT) - if (reset_state) - { - state_unbind_resources(&device->state); - } - - if (device->cs->onscreen_depth_stencil) - { - wined3d_texture_decref(device->cs->onscreen_depth_stencil->container); - device->cs->onscreen_depth_stencil = NULL; -#else /* STAGING_CSMT */ - if (device->onscreen_depth_stencil) - { - wined3d_texture_decref(device->onscreen_depth_stencil->container); - device->onscreen_depth_stencil = NULL; -#endif /* STAGING_CSMT */ - } - if (reset_state) { LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) @@ -5137,29 +4791,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } } -#if defined(STAGING_CSMT) - /* Free implicit resources and wait for the command stream before modifying - * swapchain parameters. After modifying the swapchain parameters a new GL - * context may be acquired by the worker thread. This causes problems in the - * d3d8/9 test that passes a hidden window as the new device window. - * SetPixelFormat will call SetWindowPos inside the X11 driver, which sends - * a message to the window to query the icon. Since the worker thread is - * not the thread that created the window and the d3d8 test does not run - * an event loop this deadlocks. Set up the window first from the main thread - * before calling SetPixelFormat from the worker thread to avoid this. */ - if (device->auto_depth_stencil_view) - { - wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); - device->auto_depth_stencil_view = NULL; - } - if (device->back_buffer_view) - { - wined3d_rendertarget_view_decref(device->back_buffer_view); - device->back_buffer_view = NULL; - } - device->cs->ops->finish(device->cs); - -#endif /* STAGING_CSMT */ TRACE("New params:\n"); TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width); TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height); @@ -5197,72 +4828,15 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_swapchain_set_window(swapchain, NULL); } - if (mode) - { - DisplayModeChanged = TRUE; - m = *mode; - } - else if (swapchain_desc->windowed) - { - m = swapchain->original_mode; - } - else - { - m.width = swapchain_desc->backbuffer_width; - m.height = swapchain_desc->backbuffer_height; - m.refresh_rate = swapchain_desc->refresh_rate; - m.format_id = swapchain_desc->backbuffer_format; - m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; - - if ((m.width != swapchain->desc.backbuffer_width - || m.height != swapchain->desc.backbuffer_height)) - DisplayModeChanged = TRUE; - } + backbuffer_resized = swapchain_desc->backbuffer_width != swapchain->desc.backbuffer_width + || swapchain_desc->backbuffer_height != swapchain->desc.backbuffer_height; if (!swapchain_desc->windowed != !swapchain->desc.windowed - || DisplayModeChanged) + || swapchain->reapply_mode || mode + || (!swapchain_desc->windowed && backbuffer_resized)) { - if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, &m))) - { - WARN("Failed to set display mode, hr %#x.\n", hr); - return WINED3DERR_INVALIDCALL; - } - - if (!swapchain_desc->windowed) - { - if (swapchain->desc.windowed) - { - HWND focus_window = device->create_parms.focus_window; - if (!focus_window) - focus_window = swapchain_desc->device_window; - if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window))) - { - ERR("Failed to acquire focus window, hr %#x.\n", hr); - return hr; - } - - /* switch from windowed to fs */ - wined3d_device_setup_fullscreen_window(device, swapchain->device_window, - swapchain_desc->backbuffer_width, - swapchain_desc->backbuffer_height); - } - else - { - /* Fullscreen -> fullscreen mode change */ - MoveWindow(swapchain->device_window, 0, 0, - swapchain_desc->backbuffer_width, - swapchain_desc->backbuffer_height, - TRUE); - } - swapchain->d3d_mode = m; - } - else if (!swapchain->desc.windowed) - { - /* Fullscreen -> windowed switch */ - wined3d_device_restore_fullscreen_window(device, swapchain->device_window); - wined3d_device_release_focus_window(device); - } - swapchain->desc.windowed = swapchain_desc->windowed; + if (FAILED(hr = wined3d_swapchain_set_fullscreen(swapchain, swapchain_desc, mode))) + return hr; } else if (!swapchain_desc->windowed) { @@ -5286,19 +4860,18 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) return hr; -#if !defined(STAGING_CSMT) if (device->auto_depth_stencil_view) { wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); device->auto_depth_stencil_view = NULL; } -#endif /* STAGING_CSMT */ if (swapchain->desc.enable_auto_depth_stencil) { struct wined3d_resource_desc texture_desc; struct wined3d_texture *texture; + DWORD flags = 0; - TRACE("Creating the depth stencil buffer\n"); + TRACE("Creating the depth stencil buffer.\n"); texture_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; texture_desc.format = swapchain->desc.auto_depth_stencil_format; @@ -5311,15 +4884,20 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, texture_desc.depth = 1; texture_desc.size = 0; + if (swapchain_desc->flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - device->device_parent, &texture_desc, &texture))) + device->device_parent, &texture_desc, flags, &texture))) { ERR("Failed to create the auto depth/stencil surface, hr %#x.\n", hr); return WINED3DERR_INVALIDCALL; } view_desc.format_id = texture->resource.format->id; + view_desc.flags = 0; view_desc.u.texture.level_idx = 0; + view_desc.u.texture.level_count = 1; view_desc.u.texture.layer_idx = 0; view_desc.u.texture.layer_count = 1; hr = wined3d_rendertarget_view_create(&view_desc, &texture->resource, @@ -5334,20 +4912,22 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); } -#if !defined(STAGING_CSMT) if (device->back_buffer_view) { wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; } -#endif /* STAGING_CSMT */ if (swapchain->desc.backbuffer_count) { - view_desc.format_id = swapchain_desc->backbuffer_format; + struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource; + + view_desc.format_id = back_buffer->format->id; + view_desc.flags = 0; view_desc.u.texture.level_idx = 0; + view_desc.u.texture.level_count = 1; view_desc.u.texture.layer_idx = 0; view_desc.u.texture.layer_count = 1; - if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, &swapchain->back_buffers[0]->resource, + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, back_buffer, NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); @@ -5367,46 +4947,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } wined3d_cs_emit_reset_state(device->cs); state_cleanup(&device->state); -#if defined(STAGING_CSMT) + + if (device->d3d_initialized) + wined3d_device_delete_opengl_contexts(device); + memset(&device->state, 0, sizeof(device->state)); - - if (device->d3d_initialized) - delete_opengl_contexts(device, swapchain); - - if (FAILED(hr = state_init(&device->state, &device->adapter->gl_info, - &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) -#else /* STAGING_CSMT */ - - if (device->d3d_initialized) - delete_opengl_contexts(device, swapchain); - - if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, - &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) -#endif /* STAGING_CSMT */ - ERR("Failed to initialize device state, hr %#x.\n", hr); + state_init(&device->state, &device->fb, &device->adapter->gl_info, + &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); device->update_state = &device->state; device_init_swapchain_state(device, swapchain); + if (wined3d_settings.logo) + device_load_logo(device, wined3d_settings.logo); } else if (device->back_buffer_view) { -#if defined(STAGING_CSMT) - struct wined3d_state *state = &device->state; - - wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, FALSE); - - /* Note the min_z / max_z is not reset. */ - state->viewport.x = 0; - state->viewport.y = 0; - state->viewport.width = swapchain->desc.backbuffer_width; - state->viewport.height = swapchain->desc.backbuffer_height; - wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - - state->scissor_rect.top = 0; - state->scissor_rect.left = 0; - state->scissor_rect.right = swapchain->desc.backbuffer_width; - state->scissor_rect.bottom = swapchain->desc.backbuffer_height; -#else /* STAGING_CSMT */ struct wined3d_rendertarget_view *view = device->back_buffer_view; struct wined3d_state *state = &device->state; @@ -5419,16 +4974,16 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state->viewport.height = view->height; wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - state->scissor_rect.top = 0; - state->scissor_rect.left = 0; - state->scissor_rect.right = view->width; - state->scissor_rect.bottom = view->height; -#endif /* STAGING_CSMT */ + SetRect(&state->scissor_rect, 0, 0, view->width, view->height); wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); } - if (reset_state && device->d3d_initialized) - hr = create_primary_opengl_context(device, swapchain); + if (device->d3d_initialized) + { + if (reset_state) + hr = wined3d_device_create_primary_opengl_context(device); + swapchain_update_swap_interval(swapchain); + } /* All done. There is no need to reload resources or shaders, this will happen automatically on the * first use @@ -5489,6 +5044,8 @@ void device_resource_add(struct wined3d_device *device, struct wined3d_resource { TRACE("device %p, resource %p.\n", device, resource); + wined3d_not_from_cs(device->cs); + list_add_head(&device->resources, &resource->resource_list_entry); } @@ -5496,64 +5053,39 @@ static void device_resource_remove(struct wined3d_device *device, struct wined3d { TRACE("device %p, resource %p.\n", device, resource); + wined3d_not_from_cs(device->cs); + list_remove(&resource->resource_list_entry); } void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) { enum wined3d_resource_type type = resource->type; + struct wined3d_rendertarget_view *rtv; unsigned int i; TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type)); -#if !defined(STAGING_CSMT) - context_resource_released(device, resource, type); + if (device->d3d_initialized) + { + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { + if ((rtv = device->fb.render_targets[i]) && rtv->resource == resource) + ERR("Resource %p is still in use as render target %u.\n", resource, i); + } + + if ((rtv = device->fb.depth_stencil) && rtv->resource == resource) + ERR("Resource %p is still in use as depth/stencil buffer.\n", resource); + } -#endif /* STAGING_CSMT */ switch (type) { - case WINED3D_RTYPE_SURFACE: - { - struct wined3d_surface *surface = surface_from_resource(resource); - - if (!device->d3d_initialized) break; - - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -#if defined(STAGING_CSMT) - if (wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[i]) == surface) - { - ERR("Surface %p is still in use as render target %u.\n", surface, i); - device->state.fb.render_targets[i] = NULL; - } - } - - if (wined3d_rendertarget_view_get_surface(device->state.fb.depth_stencil) == surface) - { - ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); - device->state.fb.depth_stencil = NULL; -#else /* STAGING_CSMT */ - if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface) - { - ERR("Surface %p is still in use as render target %u.\n", surface, i); - device->fb.render_targets[i] = NULL; - } - } - - if (wined3d_rendertarget_view_get_surface(device->fb.depth_stencil) == surface) - { - ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); - device->fb.depth_stencil = NULL; -#endif /* STAGING_CSMT */ - } - } - break; - + case WINED3D_RTYPE_TEXTURE_1D: case WINED3D_RTYPE_TEXTURE_2D: case WINED3D_RTYPE_TEXTURE_3D: for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) { - struct wined3d_texture *texture = wined3d_texture_from_resource(resource); + struct wined3d_texture *texture = texture_from_resource(resource); if (device->state.textures[i] == texture) { @@ -5666,19 +5198,8 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, return hr; } - device->blitter = adapter->blitter; - -#if defined(STAGING_CSMT) - if (FAILED(hr = state_init(&device->state, &adapter->gl_info, - &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) -#else /* STAGING_CSMT */ - if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, - &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) -#endif /* STAGING_CSMT */ - { - ERR("Failed to initialize device state, hr %#x.\n", hr); - goto err; - } + state_init(&device->state, &device->fb, &adapter->gl_info, + &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); device->update_state = &device->state; if (!(device->cs = wined3d_cs_create(device))) @@ -5701,7 +5222,6 @@ err: return hr; } - void device_invalidate_state(const struct wined3d_device *device, DWORD state) { DWORD rep = device->StateTable[state].representative; @@ -5710,6 +5230,15 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state) BYTE shift; UINT i; + wined3d_from_cs(device->cs); + + if (STATE_IS_COMPUTE(state)) + { + for (i = 0; i < device->context_count; ++i) + context_invalidate_compute_state(device->contexts[i], state); + return; + } + for (i = 0; i < device->context_count; ++i) { context = device->contexts[i]; diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index ed5e9c37518..0d5a71f915f 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -30,7 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(winediag); -#define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024) #define DEFAULT_REFRESH_RATE 0 /* The driver names reflect the lowest GPU supported @@ -42,10 +41,12 @@ enum wined3d_display_driver DRIVER_AMD_R100, DRIVER_AMD_R300, DRIVER_AMD_R600, + DRIVER_AMD_RX, DRIVER_INTEL_GMA800, DRIVER_INTEL_GMA900, DRIVER_INTEL_GMA950, DRIVER_INTEL_GMA3000, + DRIVER_INTEL_HD4000, DRIVER_NVIDIA_TNT, DRIVER_NVIDIA_GEFORCE2MX, DRIVER_NVIDIA_GEFORCEFX, @@ -57,6 +58,7 @@ enum wined3d_display_driver enum wined3d_driver_model { + DRIVER_MODEL_GENERIC, DRIVER_MODEL_WIN9X, DRIVER_MODEL_NT40, DRIVER_MODEL_NT5X, @@ -105,19 +107,30 @@ static const struct wined3d_extension_map gl_extension_map[] = /* ARB */ {"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED }, + {"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT }, + {"GL_ARB_clear_texture", ARB_CLEAR_TEXTURE }, + {"GL_ARB_clip_control", ARB_CLIP_CONTROL }, {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT }, + {"GL_ARB_compute_shader", ARB_COMPUTE_SHADER }, + {"GL_ARB_copy_buffer", ARB_COPY_BUFFER }, {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT }, {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT }, {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, + {"GL_ARB_derivative_control", ARB_DERIVATIVE_CONTROL }, {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED }, {"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY }, + {"GL_ARB_ES3_compatibility", ARB_ES3_COMPATIBILITY }, + {"GL_ARB_explicit_attrib_location", ARB_EXPLICIT_ATTRIB_LOCATION }, + {"GL_ARB_fragment_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS}, + {"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT }, {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, {"GL_ARB_framebuffer_sRGB", ARB_FRAMEBUFFER_SRGB }, {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4 }, + {"GL_ARB_gpu_shader5", ARB_GPU_SHADER5 }, {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL }, {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX }, {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS }, @@ -128,23 +141,38 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_multisample", ARB_MULTISAMPLE }, {"GL_ARB_multitexture", ARB_MULTITEXTURE }, {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY }, + {"GL_ARB_pipeline_statistics_query", ARB_PIPELINE_STATISTICS_QUERY }, {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT }, {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS }, {"GL_ARB_point_sprite", ARB_POINT_SPRITE }, {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX }, {"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS }, + {"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP }, + {"GL_ARB_shader_atomic_counters", ARB_SHADER_ATOMIC_COUNTERS }, {"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING }, + {"GL_ARB_shader_image_load_store", ARB_SHADER_IMAGE_LOAD_STORE }, + {"GL_ARB_shader_image_size", ARB_SHADER_IMAGE_SIZE }, + {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT}, {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD }, {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 }, + {"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK }, + {"GL_ARB_shading_language_packing", ARB_SHADING_LANGUAGE_PACKING }, {"GL_ARB_shadow", ARB_SHADOW }, + {"GL_ARB_stencil_texturing", ARB_STENCIL_TEXTURING }, {"GL_ARB_sync", ARB_SYNC }, + {"GL_ARB_tessellation_shader", ARB_TESSELLATION_SHADER }, {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP }, + {"GL_ARB_texture_buffer_object", ARB_TEXTURE_BUFFER_OBJECT }, + {"GL_ARB_texture_buffer_range", ARB_TEXTURE_BUFFER_RANGE }, {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION }, + {"GL_ARB_texture_compression_bptc", ARB_TEXTURE_COMPRESSION_BPTC }, {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC }, {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP }, + {"GL_ARB_texture_cube_map_array", ARB_TEXTURE_CUBE_MAP_ARRAY }, {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE }, {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3 }, {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT }, + {"GL_ARB_texture_gather", ARB_TEXTURE_GATHER }, {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT }, {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE}, {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO }, @@ -152,13 +180,20 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE }, {"GL_ARB_texture_rg", ARB_TEXTURE_RG }, {"GL_ARB_texture_rgb10_a2ui", ARB_TEXTURE_RGB10_A2UI }, + {"GL_ARB_texture_storage", ARB_TEXTURE_STORAGE }, + {"GL_ARB_texture_swizzle", ARB_TEXTURE_SWIZZLE }, + {"GL_ARB_texture_view", ARB_TEXTURE_VIEW }, {"GL_ARB_timer_query", ARB_TIMER_QUERY }, + {"GL_ARB_transform_feedback2", ARB_TRANSFORM_FEEDBACK2 }, + {"GL_ARB_transform_feedback3", ARB_TRANSFORM_FEEDBACK3 }, {"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT }, {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND }, {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT }, {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM }, {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, + {"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV}, + {"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY }, /* ATI */ {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER }, @@ -182,12 +217,14 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS }, {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4 }, {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL }, + {"GL_EXT_packed_float", EXT_PACKED_FLOAT }, {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS }, {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX }, {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR }, {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE }, {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP }, {"GL_EXT_texture3D", EXT_TEXTURE3D }, + {"GL_EXT_texture_array", EXT_TEXTURE_ARRAY }, {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC }, {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC }, {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE }, @@ -196,6 +233,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_EXT_texture_integer", EXT_TEXTURE_INTEGER }, {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS }, {"GL_EXT_texture_mirror_clamp", EXT_TEXTURE_MIRROR_CLAMP }, + {"GL_EXT_texture_shared_exponent", EXT_TEXTURE_SHARED_EXPONENT }, {"GL_EXT_texture_snorm", EXT_TEXTURE_SNORM }, {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB }, {"GL_EXT_texture_sRGB_decode", EXT_TEXTURE_SRGB_DECODE }, @@ -232,7 +270,7 @@ static const struct wined3d_extension_map wgl_extension_map[] = {"WGL_ARB_pixel_format", WGL_ARB_PIXEL_FORMAT }, {"WGL_EXT_swap_control", WGL_EXT_SWAP_CONTROL }, {"WGL_WINE_pixel_format_passthrough", WGL_WINE_PIXEL_FORMAT_PASSTHROUGH}, - {"WGL_WINE_gpu_info", WGL_WINE_GPU_INFO }, + {"WGL_WINE_query_renderer", WGL_WINE_QUERY_RENDERER }, }; /********************************************************** @@ -469,8 +507,9 @@ static BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info) return ret; } -static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { if (card_vendor != HW_VENDOR_AMD) return FALSE; if (device == CARD_AMD_RADEON_9500) return TRUE; @@ -479,8 +518,9 @@ static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, const c return FALSE; } -static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { if (card_vendor == HW_VENDOR_NVIDIA) { @@ -494,8 +534,9 @@ static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl return FALSE; } -static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_apple(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to @@ -511,11 +552,7 @@ static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_re * * This test has been moved into wined3d_guess_gl_vendor() */ - if (gl_vendor == GL_VENDOR_APPLE) - { - return TRUE; - } - return FALSE; + return gl_vendor == GL_VENDOR_APPLE; } /* Context activation is done by the caller. */ @@ -584,14 +621,16 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info) } } -static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE); } -static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { if (gl_vendor != GL_VENDOR_APPLE) return FALSE; if (card_vendor != HW_VENDOR_AMD) return FALSE; @@ -599,8 +638,9 @@ static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const return TRUE; } -static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card. @@ -612,15 +652,17 @@ static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char return gl_info->limits.glsl_varyings > 44; } -static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { - return !match_dx10_capable(gl_info, gl_renderer, gl_vendor, card_vendor, device); + return !match_dx10_capable(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device); } /* A GL context is provided by the caller */ -static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { GLenum error; DWORD data[16]; @@ -646,8 +688,9 @@ static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const } /* A GL context is provided by the caller */ -static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { GLuint prog; BOOL ret = FALSE; @@ -690,8 +733,9 @@ static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const ch } /* Context activation is done by the caller. */ -static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { char data[4 * 4 * 4]; GLuint tex, fbo; @@ -741,8 +785,9 @@ static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const ch } /* Context activation is done by the caller. */ -static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards. * This leads to graphical bugs in Half Life 2 and Unreal engine games. */ @@ -766,22 +811,25 @@ static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, const cha return size < 16; } -static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { return gl_vendor == GL_VENDOR_FGLRX; } -static BOOL match_r200(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_r200(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { if (card_vendor != HW_VENDOR_AMD) return FALSE; if (device == CARD_AMD_RADEON_8500) return TRUE; return FALSE; } -static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { DWORD data[4]; GLuint tex, fbo; @@ -875,6 +923,17 @@ static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, const ch return data[0] != 0x00ff0000 || data[3] != 0x0000ff00; } +static BOOL match_broken_viewport_subpixel_bits(const struct wined3d_gl_info *gl_info, + struct wined3d_caps_gl_ctx *ctx, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + if (!gl_info->supported[ARB_VIEWPORT_ARRAY]) + return FALSE; + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return FALSE; + return !wined3d_caps_gl_ctx_test_viewport_subpixel_bits(ctx); +} + static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info) { /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms. @@ -1003,10 +1062,20 @@ static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info) gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG; } +static void quirk_broken_viewport_subpixel_bits(struct wined3d_gl_info *gl_info) +{ + if (gl_info->supported[ARB_CLIP_CONTROL]) + { + TRACE("Disabling ARB_clip_control.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } +} + struct driver_quirk { - BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device); + BOOL (*match)(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device); void (*apply)(struct wined3d_gl_info *gl_info); const char *description; }; @@ -1093,6 +1162,11 @@ static const struct driver_quirk quirk_table[] = quirk_broken_arb_fog, "ARBfp fogstart == fogend workaround" }, + { + match_broken_viewport_subpixel_bits, + quirk_broken_viewport_subpixel_bits, + "Nvidia viewport subpixel bits bug" + }, }; /* Certain applications (Steam) complain if we report an outdated driver version. In general, @@ -1146,7 +1220,8 @@ static const struct driver_version_information driver_version_table[] = {DRIVER_AMD_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764}, {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 17, 10, 1280}, {DRIVER_AMD_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 }, - {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 17, 10, 1280 }, + {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 17, 10, 1280}, + {DRIVER_AMD_RX, DRIVER_MODEL_NT6X, "aticfx32.dll", 17, 10, 1474}, /* Intel * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp @@ -1158,6 +1233,7 @@ static const struct driver_version_information driver_version_table[] = {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 5218}, {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT6X, "igdumd32.dll", 14, 10, 1504}, {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666}, + {DRIVER_INTEL_HD4000, DRIVER_MODEL_NT6X, "igdumdim32.dll", 19, 15, 4352}, /* Nvidia * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8 @@ -1224,11 +1300,13 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400M, "NVIDIA GeForce 9400M", DRIVER_NVIDIA_GEFORCE8, 256 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", DRIVER_NVIDIA_GEFORCE8, 256 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", DRIVER_NVIDIA_GEFORCE8, 256 }, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE8, 384 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9700MGT, "NVIDIA GeForce 9700M GT", DRIVER_NVIDIA_GEFORCE8, 512 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", DRIVER_NVIDIA_GEFORCE8, 512 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", DRIVER_NVIDIA_GEFORCE8, 512 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", DRIVER_NVIDIA_GEFORCE8, 512 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", DRIVER_NVIDIA_GEFORCE8, 512 }, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS250, "NVIDIA GeForce GTS 250", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE8, 896 }, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE8, 1024}, @@ -1250,10 +1328,12 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", DRIVER_NVIDIA_GEFORCE8, 1280}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", DRIVER_NVIDIA_GEFORCE8, 1536}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT520, "NVIDIA GeForce GT 520", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT525M, "NVIDIA GeForce GT 525M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT540M, "NVIDIA GeForce GT 540M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX550, "NVIDIA GeForce GTX 550 Ti", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT555M, "NVIDIA GeForce GT 555M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560TI, "NVIDIA GeForce GTX 560 Ti", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560M, "NVIDIA GeForce GTX 560M", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560, "NVIDIA GeForce GTX 560", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX570, "NVIDIA GeForce GTX 570", DRIVER_NVIDIA_GEFORCE8, 1280}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX580, "NVIDIA GeForce GTX 580", DRIVER_NVIDIA_GEFORCE8, 1536}, @@ -1269,18 +1349,49 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX675MX, "NVIDIA GeForce GTX 675MX", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX690, "NVIDIA GeForce GTX 690", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT730, "NVIDIA GeForce GT 730", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT730M, "NVIDIA GeForce GT 730M", DRIVER_NVIDIA_GEFORCE8, 1024}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT740M, "NVIDIA GeForce GT 740M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT750M, "NVIDIA GeForce GT 750M", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750, "NVIDIA GeForce GTX 750", DRIVER_NVIDIA_GEFORCE8, 1024}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX750TI, "NVIDIA GeForce GTX 750 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, - {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760, "NVIDIA Geforce GTX 760", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760, "NVIDIA GeForce GTX 760", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX760TI, "NVIDIA GeForce GTX 760 Ti", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX765M, "NVIDIA GeForce GTX 765M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770, "NVIDIA GeForce GTX 770", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780, "NVIDIA GeForce GTX 780", DRIVER_NVIDIA_GEFORCE8, 3072}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX780TI, "NVIDIA GeForce GTX 780 Ti", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITAN, "NVIDIA GeForce GTX TITAN", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITANB, "NVIDIA GeForce GTX TITAN Black", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITANX, "NVIDIA GeForce GTX TITAN X", DRIVER_NVIDIA_GEFORCE8, 12288}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTXTITANZ, "NVIDIA GeForce GTX TITAN Z", DRIVER_NVIDIA_GEFORCE8, 12288}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_820M, "NVIDIA GeForce 820M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_830M, "NVIDIA GeForce 830M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_840M, "NVIDIA GeForce 840M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_845M, "NVIDIA GeForce 845M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX850M, "NVIDIA GeForce GTX 850M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX860M, "NVIDIA GeForce GTX 860M", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX870M, "NVIDIA GeForce GTX 870M", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX880M, "NVIDIA GeForce GTX 880M", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_940M, "NVIDIA GeForce 940M", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX950, "NVIDIA GeForce GTX 950", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX950M, "NVIDIA GeForce GTX 950M", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX960, "NVIDIA GeForce GTX 960", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX960M, "NVIDIA GeForce GTX 960M", DRIVER_NVIDIA_GEFORCE8, 2048}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX970, "NVIDIA GeForce GTX 970", DRIVER_NVIDIA_GEFORCE8, 4096}, {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX970M, "NVIDIA GeForce GTX 970M", DRIVER_NVIDIA_GEFORCE8, 3072}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980, "NVIDIA GeForce GTX 980", DRIVER_NVIDIA_GEFORCE8, 4096}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980TI, "NVIDIA GeForce GTX 980 Ti", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050, "NVIDIA GeForce GTX 1050", DRIVER_NVIDIA_GEFORCE8, 2048}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1060, "NVIDIA GeForce GTX 1060", DRIVER_NVIDIA_GEFORCE8, 6144}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1070, "NVIDIA GeForce GTX 1070", DRIVER_NVIDIA_GEFORCE8, 8192}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080, "NVIDIA GeForce GTX 1080", DRIVER_NVIDIA_GEFORCE8, 8192}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080TI, "NVIDIA GeForce GTX 1080 Ti", DRIVER_NVIDIA_GEFORCE8, 11264}, + {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANX_PASCAL, "NVIDIA TITAN X (Pascal)", DRIVER_NVIDIA_GEFORCE8, 12288}, /* AMD cards */ {HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 }, @@ -1308,6 +1419,7 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6300, "AMD Radeon HD 6300 series Graphics", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6400, "AMD Radeon HD 6400 Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6410D, "AMD Radeon HD 6410D", DRIVER_AMD_R600, 1024}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6480G, "AMD Radeon HD 6480G", DRIVER_AMD_R600, 512 }, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6550D, "AMD Radeon HD 6550D", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600, "AMD Radeon HD 6600 Series", DRIVER_AMD_R600, 1024}, {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600M, "AMD Radeon HD 6600M Series", DRIVER_AMD_R600, 512 }, @@ -1323,7 +1435,11 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_AMD, CARD_AMD_RADEON_HD8770, "AMD Radeon HD 8770", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_R3, "AMD Radeon HD 8400 / R3 Series", DRIVER_AMD_R600, 2048}, {HW_VENDOR_AMD, CARD_AMD_RADEON_R7, "AMD Radeon(TM) R7 Graphics", DRIVER_AMD_R600, 2048}, - {HW_VENDOR_AMD, CARD_AMD_RADEON_R9, "AMD Radeon R9 290", DRIVER_AMD_R600, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_285, "AMD Radeon R9 285", DRIVER_AMD_RX, 2048}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_290, "AMD Radeon R9 290", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_R9_FURY, "AMD Radeon (TM) R9 Fury Series", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_460, "Radeon(TM) RX 460 Graphics", DRIVER_AMD_RX, 4096}, + {HW_VENDOR_AMD, CARD_AMD_RADEON_RX_480, "Radeon (TM) RX 480 Graphics", DRIVER_AMD_RX, 4096}, /* VMware */ {HW_VENDOR_VMWARE, CARD_VMWARE_SVGA3D, "VMware SVGA 3D (Microsoft Corporation - WDDM)", DRIVER_VMWARE, 1024}, @@ -1355,15 +1471,49 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_Q45, "Intel(R) Q45/Q43", DRIVER_INTEL_GMA3000, 512}, {HW_VENDOR_INTEL, CARD_INTEL_G41, "Intel(R) G41", DRIVER_INTEL_GMA3000, 512}, {HW_VENDOR_INTEL, CARD_INTEL_B43, "Intel(R) B43", DRIVER_INTEL_GMA3000, 512}, - {HW_VENDOR_INTEL, CARD_INTEL_ILKD, "Intel(R) Ironlake Desktop", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_ILKM, "Intel(R) Ironlake Mobile", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_SNBD, "Intel(R) Sandybridge Desktop", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_SNBM, "Intel(R) Sandybridge Mobile", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_SNBS, "Intel(R) Sandybridge Server", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_IVBD, "Intel(R) Ivybridge Desktop", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_IVBM, "Intel(R) Ivybridge Mobile", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) Ivybridge Server", DRIVER_INTEL_GMA3000, 1024}, - {HW_VENDOR_INTEL, CARD_INTEL_HWM, "Intel(R) Haswell Mobile", DRIVER_INTEL_GMA3000, 1024}, + {HW_VENDOR_INTEL, CARD_INTEL_ILKD, "Intel(R) HD Graphics", DRIVER_INTEL_GMA3000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_ILKM, "Intel(R) HD Graphics", DRIVER_INTEL_GMA3000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_SNBD, "Intel(R) HD Graphics 3000", DRIVER_INTEL_GMA3000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_SNBM, "Intel(R) HD Graphics 3000", DRIVER_INTEL_GMA3000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_SNBS, "Intel(R) HD Graphics Family", DRIVER_INTEL_GMA3000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IVBD, "Intel(R) HD Graphics 4000", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IVBM, "Intel(R) HD Graphics 4000", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) HD Graphics Family", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_HWD, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_HWM, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_I5100_1, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_I5100_2, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_I5100_3, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_I5100_4, "Intel(R) Iris(TM) Graphics 5100", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_1, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_2, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_3, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_4, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_IP5200_5, "Intel(R) Iris(TM) Pro Graphics 5200", DRIVER_INTEL_HD4000, 1536}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5300, "Intel(R) HD Graphics 5300", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5500, "Intel(R) HD Graphics 5500", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5600, "Intel(R) HD Graphics 5600", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD6000, "Intel(R) HD Graphics 6000", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I6100, "Intel(R) Iris(TM) Graphics 6100", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP6200, "Intel(R) Iris(TM) Pro Graphics 6200", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IPP6300, "Intel(R) Iris(TM) Pro Graphics P6300", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_1, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_2, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_3, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD515, "Intel(R) HD Graphics 515", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD520_1, "Intel(R) HD Graphics 520", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD520_2, "Intel(R) HD Graphics 520", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD530_1, "Intel(R) HD Graphics 530", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD530_2, "Intel(R) HD Graphics 530", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HDP530, "Intel(R) HD Graphics P530", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I540, "Intel(R) Iris(TM) Graphics 540", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I550, "Intel(R) Iris(TM) Graphics 550", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I555, "Intel(R) Iris(TM) Graphics 555", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP555, "Intel(R) Iris(TM) Graphics P555", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP580_1, "Intel(R) Iris(TM) Pro Graphics 580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP580_2, "Intel(R) Iris(TM) Pro Graphics 580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IPP580_1, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IPP580_2, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, }; static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver, @@ -1376,7 +1526,8 @@ static const struct driver_version_information *get_driver_version_info(enum win { const struct driver_version_information *entry = &driver_version_table[i]; - if (entry->driver == driver && entry->driver_model == driver_model) + if (entry->driver == driver && (driver_model == DRIVER_MODEL_GENERIC + || entry->driver_model == driver_model)) { TRACE("Found driver \"%s\", version %u, subversion %u, build %u.\n", entry->driver_name, entry->version, entry->subversion, entry->build); @@ -1400,56 +1551,71 @@ static const struct gpu_description *get_gpu_description(enum wined3d_pci_vendor return NULL; } -/* Context activation is done by the caller. */ -static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_driver_info *driver_info, - enum wined3d_pci_vendor vendor, enum wined3d_pci_device device) +static const struct gpu_description *query_gpu_description(const struct wined3d_gl_info *gl_info, UINT64 *vram_bytes) +{ + enum wined3d_pci_vendor vendor = PCI_VENDOR_NONE; + enum wined3d_pci_device device = PCI_DEVICE_NONE; + const struct gpu_description *gpu_description; + static unsigned int once; + + if (gl_info->supported[WGL_WINE_QUERY_RENDERER]) + { + GLuint value; + + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VENDOR_ID_WINE, &value))) + vendor = value; + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_DEVICE_ID_WINE, &value))) + device = value; + if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VIDEO_MEMORY_WINE, &value))) + *vram_bytes = (UINT64)value * 1024 * 1024; + TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n", + vendor, device, wine_dbgstr_longlong(*vram_bytes)); + } + else if (gl_info->supported[NVX_GPU_MEMORY_INFO]) + { + GLint vram_kb; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb); + + *vram_bytes = (UINT64)vram_kb * 1024; + TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n", + wine_dbgstr_longlong(*vram_bytes)); + } + + if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE) + { + vendor = wined3d_settings.pci_vendor_id; + TRACE("Overriding vendor PCI ID with 0x%04x.\n", vendor); + } + + if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE) + { + device = wined3d_settings.pci_device_id; + TRACE("Overriding device PCI ID with 0x%04x.\n", device); + } + + if (wined3d_settings.emulated_textureram) + { + *vram_bytes = wined3d_settings.emulated_textureram; + TRACE("Overriding amount of video memory with 0x%s bytes.\n", + wine_dbgstr_longlong(*vram_bytes)); + } + + if (!(gpu_description = get_gpu_description(vendor, device)) + && (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE + || wined3d_settings.pci_device_id != PCI_DEVICE_NONE) && !once++) + ERR_(winediag)("Invalid GPU override %04x:%04x specified, ignoring.\n", vendor, device); + + return gpu_description; +} + +static void init_driver_info(struct wined3d_driver_info *driver_info, + const struct gpu_description *gpu_desc, UINT64 vram_bytes) { OSVERSIONINFOW os_version; WORD driver_os_version; enum wined3d_display_driver driver; enum wined3d_driver_model driver_model; const struct driver_version_information *version_info; - const struct gpu_description *gpu_desc; - - if (driver_info->vendor != PCI_VENDOR_NONE || driver_info->device != PCI_DEVICE_NONE) - { - static unsigned int once; - unsigned int real_vendor, real_device; - - TRACE("GPU override %04x:%04x.\n", wined3d_settings.pci_vendor_id, wined3d_settings.pci_device_id); - - if (gl_info->supported[WGL_WINE_GPU_INFO] && - gl_info->gl_ops.ext.p_wglGetPCIInfoWINE(&real_vendor, &real_device)) - { - if (get_gpu_description(real_vendor, real_device)) - { - vendor = real_vendor; - device = real_device; - } - else if (!once++) - ERR_(winediag)("Could not find GPU info for %04x:%04x.\n", real_vendor, real_device); - } - - driver_info->vendor = wined3d_settings.pci_vendor_id; - if (driver_info->vendor == PCI_VENDOR_NONE) - driver_info->vendor = vendor; - - driver_info->device = wined3d_settings.pci_device_id; - if (driver_info->device == PCI_DEVICE_NONE) - driver_info->device = device; - - if (get_gpu_description(driver_info->vendor, driver_info->device)) - { - vendor = driver_info->vendor; - device = driver_info->device; - } - else if (!once++) - ERR_(winediag)("Invalid GPU override %04x:%04x specified, ignoring.\n", - driver_info->vendor, driver_info->device); - } - - driver_info->vendor = vendor; - driver_info->device = device; memset(&os_version, 0, sizeof(os_version)); os_version.dwOSVersionInfoSize = sizeof(os_version); @@ -1500,6 +1666,11 @@ static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_dri } break; + case 10: + driver_os_version = 10; + driver_model = DRIVER_MODEL_NT6X; + break; + default: FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n", os_version.dwMajorVersion, os_version.dwMinorVersion); @@ -1509,47 +1680,24 @@ static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_dri } } - if ((gpu_desc = get_gpu_description(driver_info->vendor, driver_info->device))) - { - driver_info->description = gpu_desc->description; - driver_info->vram_bytes = (UINT64)gpu_desc->vidmem * 1024 * 1024; - driver = gpu_desc->driver; - } - else - { - ERR("Card %04x:%04x not found in driver DB.\n", vendor, device); - driver_info->description = "Direct3D HAL"; - driver_info->vram_bytes = WINE_DEFAULT_VIDMEM; - driver = DRIVER_UNKNOWN; - } + driver_info->vendor = gpu_desc->vendor; + driver_info->device = gpu_desc->card; + driver_info->description = gpu_desc->description; + driver_info->vram_bytes = vram_bytes ? vram_bytes : (UINT64)gpu_desc->vidmem * 1024 * 1024; + driver = gpu_desc->driver; - if (gl_info->supported[NVX_GPU_MEMORY_INFO]) + /** + * Diablo 2 crashes when the amount of video memory is greater than 0x7fffffff. + * In order to avoid this application bug we limit the amount of video memory + * to LONG_MAX for older Windows versions. + */ +#ifdef __i386__ + if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX) { - GLint vram_kb; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb); - - driver_info->vram_bytes = (UINT64)vram_kb * 1024; - TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n", - wine_dbgstr_longlong(driver_info->vram_bytes)); - } - - if (gl_info->supported[WGL_WINE_GPU_INFO]) - { - unsigned int vram_mb; - if (gl_info->gl_ops.ext.p_wglGetMemoryInfoWINE(&vram_mb)) - { - driver_info->vram_bytes = (UINT64)vram_mb * 1024 * 1024; - TRACE("Got 0x%s as video memory from wglGetGPUInfoWINE.\n", - wine_dbgstr_longlong(driver_info->vram_bytes)); - } - } - - if (wined3d_settings.emulated_textureram) - { - TRACE("Overriding amount of video memory with 0x%s bytes.\n", - wine_dbgstr_longlong(wined3d_settings.emulated_textureram)); - driver_info->vram_bytes = wined3d_settings.emulated_textureram; + TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX); + driver_info->vram_bytes = LONG_MAX; } +#endif /* Try to obtain driver version information for the current Windows version. This fails in * some cases: @@ -1565,7 +1713,7 @@ static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_dri * This could be an indication that our database is not up to date, so this should be fixed. */ if ((version_info = get_driver_version_info(driver, driver_model)) - || (version_info = get_driver_version_info(driver, DRIVER_MODEL_NT5X))) + || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC))) { driver_info->name = version_info->driver_name; driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version); @@ -1574,7 +1722,7 @@ static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_dri else { ERR("No driver version info found for device %04x:%04x, driver model %#x.\n", - vendor, device, driver_model); + driver_info->vendor, driver_info->device, driver_model); driver_info->name = "Display"; driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15); driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */ @@ -1585,14 +1733,15 @@ static void init_driver_info(struct wined3d_gl_info *gl_info, struct wined3d_dri } /* Context activation is done by the caller. */ -static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer, - enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +static void fixup_extensions(struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx, + const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, + enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { unsigned int i; for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i) { - if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue; + if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device)) continue; TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description); quirk_table[i].apply(gl_info); } @@ -1624,7 +1773,6 @@ static DWORD wined3d_parse_gl_version(const char *gl_version) static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info, const char *gl_vendor_string, const char *gl_renderer) { - /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to * detect the Apple OpenGL implementation to apply some extension fixups afterwards. @@ -1636,8 +1784,7 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_in * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So * the chance that other implementations support them is rather small since Win32 QuickTime uses * DirectDraw, not OpenGL. */ - if (gl_info->supported[APPLE_FENCE] - && gl_info->supported[APPLE_YCBCR_422]) + if (gl_info->supported[APPLE_FENCE] && gl_info->supported[APPLE_YCBCR_422]) return GL_VENDOR_APPLE; if (strstr(gl_vendor_string, "NVIDIA")) @@ -1647,6 +1794,7 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_in return GL_VENDOR_FGLRX; if (strstr(gl_vendor_string, "Mesa") + || strstr(gl_vendor_string, "Brian Paul") || strstr(gl_vendor_string, "X.Org") || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.") || strstr(gl_vendor_string, "DRI R300 Project") @@ -1708,16 +1856,13 @@ static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shad if (shader_caps->vs_version >= 5) return WINED3D_D3D_LEVEL_11; if (shader_caps->vs_version == 4) - { - /* No backed supports SM 5 at the moment */ - if (glsl_version >= MAKEDWORD_VERSION(4, 00)) - return WINED3D_D3D_LEVEL_11; return WINED3D_D3D_LEVEL_10; - } if (shader_caps->vs_version == 3) { - /* Wine cannot use SM 4 on mesa drivers as the necessary functionality - * is not exposed on compatibility contexts */ + /* wined3d with default settings at the moment doesn't expose SM4+ on + * Mesa drivers. */ + if (glsl_version >= MAKEDWORD_VERSION(4, 30)) + return WINED3D_D3D_LEVEL_11; if (glsl_version >= MAKEDWORD_VERSION(1, 30)) return WINED3D_D3D_LEVEL_10; return WINED3D_D3D_LEVEL_9_SM3; @@ -1743,18 +1888,49 @@ static const struct wined3d_renderer_table cards_nvidia_binary[] = { /* Direct 3D 11 */ + {"TITAN X (Pascal)", CARD_NVIDIA_TITANX_PASCAL}, /* GeForce 1000 - highend */ + {"GTX 1080 Ti", CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */ + {"GTX 1080", CARD_NVIDIA_GEFORCE_GTX1080}, /* GeForce 1000 - highend */ + {"GTX 1070", CARD_NVIDIA_GEFORCE_GTX1070}, /* GeForce 1000 - highend */ + {"GTX 1060", CARD_NVIDIA_GEFORCE_GTX1060}, /* GeForce 1000 - midend high */ + {"GTX 1050", CARD_NVIDIA_GEFORCE_GTX1050}, /* GeForce 1000 - midend */ + {"GTX 980 Ti", CARD_NVIDIA_GEFORCE_GTX980TI}, /* GeForce 900 - highend */ + {"GTX 980", CARD_NVIDIA_GEFORCE_GTX980}, /* GeForce 900 - highend */ {"GTX 970M", CARD_NVIDIA_GEFORCE_GTX970M}, /* GeForce 900 - highend mobile*/ {"GTX 970", CARD_NVIDIA_GEFORCE_GTX970}, /* GeForce 900 - highend */ + {"GTX TITAN X", CARD_NVIDIA_GEFORCE_GTXTITANX}, /* Geforce 900 - highend */ + {"GTX 960M", CARD_NVIDIA_GEFORCE_GTX960M}, /* GeForce 900 - midend high mobile */ + {"GTX 960", CARD_NVIDIA_GEFORCE_GTX960}, /* GeForce 900 - midend high */ + {"GTX 950M", CARD_NVIDIA_GEFORCE_GTX950M}, /* GeForce 900 - midend mobile */ + {"GTX 950", CARD_NVIDIA_GEFORCE_GTX950}, /* GeForce 900 - midend */ + {"GeForce 940M", CARD_NVIDIA_GEFORCE_940M}, /* GeForce 900 - midend mobile */ + {"GTX 880M", CARD_NVIDIA_GEFORCE_GTX880M}, /* GeForce 800 - mobile */ + {"GTX 870M", CARD_NVIDIA_GEFORCE_GTX870M}, /* GeForce 800 - mobile */ + {"GTX 860M", CARD_NVIDIA_GEFORCE_GTX860M}, /* GeForce 800 - mobile */ + {"GTX 850M", CARD_NVIDIA_GEFORCE_GTX850M}, /* GeForce 800 - mobile */ + {"GeForce 845M", CARD_NVIDIA_GEFORCE_845M}, /* GeForce 800 - mobile */ + {"GeForce 840M", CARD_NVIDIA_GEFORCE_840M}, /* GeForce 800 - mobile */ + {"GeForce 830M", CARD_NVIDIA_GEFORCE_830M}, /* GeForce 800 - mobile */ + {"GeForce 820M", CARD_NVIDIA_GEFORCE_820M}, /* GeForce 800 - mobile */ {"GTX 780 Ti", CARD_NVIDIA_GEFORCE_GTX780TI}, /* Geforce 700 - highend */ + {"GTX TITAN Black", CARD_NVIDIA_GEFORCE_GTXTITANB}, /* Geforce 700 - highend */ + {"GTX TITAN Z", CARD_NVIDIA_GEFORCE_GTXTITANZ}, /* Geforce 700 - highend */ + {"GTX TITAN", CARD_NVIDIA_GEFORCE_GTXTITAN}, /* Geforce 700 - highend */ {"GTX 780", CARD_NVIDIA_GEFORCE_GTX780}, /* Geforce 700 - highend */ {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */ {"GTX 770", CARD_NVIDIA_GEFORCE_GTX770}, /* Geforce 700 - highend */ {"GTX 765M", CARD_NVIDIA_GEFORCE_GTX765M}, /* Geforce 700 - midend high mobile */ + {"GTX 760 Ti", CARD_NVIDIA_GEFORCE_GTX760TI}, /* Geforce 700 - midend high */ {"GTX 760", CARD_NVIDIA_GEFORCE_GTX760}, /* Geforce 700 - midend high */ {"GTX 750 Ti", CARD_NVIDIA_GEFORCE_GTX750TI}, /* Geforce 700 - midend */ {"GTX 750", CARD_NVIDIA_GEFORCE_GTX750}, /* Geforce 700 - midend */ {"GT 750M", CARD_NVIDIA_GEFORCE_GT750M}, /* Geforce 700 - midend mobile */ + {"GT 740M", CARD_NVIDIA_GEFORCE_GT740M}, /* Geforce 700 - midend mobile */ + {"GT 730M", CARD_NVIDIA_GEFORCE_GT730M}, /* Geforce 700 - midend mobile */ + {"GT 730", CARD_NVIDIA_GEFORCE_GT730}, /* Geforce 700 - lowend */ + {"GTX 690", CARD_NVIDIA_GEFORCE_GTX690}, /* Geforce 600 - highend */ {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */ + {"GTX 675MX", CARD_NVIDIA_GEFORCE_GTX675MX}, /* Geforce 600 - highend */ {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */ {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */ {"GTX 660 Ti", CARD_NVIDIA_GEFORCE_GTX660TI}, /* Geforce 600 - midend high */ @@ -1770,10 +1946,12 @@ cards_nvidia_binary[] = {"GTX 580", CARD_NVIDIA_GEFORCE_GTX580}, /* Geforce 500 - highend */ {"GTX 570", CARD_NVIDIA_GEFORCE_GTX570}, /* Geforce 500 - midend high */ {"GTX 560 Ti", CARD_NVIDIA_GEFORCE_GTX560TI}, /* Geforce 500 - midend */ + {"GTX 560M", CARD_NVIDIA_GEFORCE_GTX560M}, /* Geforce 500 - midend mobile */ {"GTX 560", CARD_NVIDIA_GEFORCE_GTX560}, /* Geforce 500 - midend */ {"GT 555M", CARD_NVIDIA_GEFORCE_GT555M}, /* Geforce 500 - midend mobile */ {"GTX 550 Ti", CARD_NVIDIA_GEFORCE_GTX550}, /* Geforce 500 - midend */ {"GT 540M", CARD_NVIDIA_GEFORCE_GT540M}, /* Geforce 500 - midend mobile */ + {"GT 525M", CARD_NVIDIA_GEFORCE_GT525M}, /* Geforce 500 - lowend mobile */ {"GT 520", CARD_NVIDIA_GEFORCE_GT520}, /* Geforce 500 - lowend */ {"GTX 480", CARD_NVIDIA_GEFORCE_GTX480}, /* Geforce 400 - highend */ {"GTX 470", CARD_NVIDIA_GEFORCE_GTX470}, /* Geforce 400 - midend high */ @@ -1800,15 +1978,16 @@ cards_nvidia_binary[] = {"GTX 280", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */ {"GTX 275", CARD_NVIDIA_GEFORCE_GTX275}, /* Geforce 200 - midend high */ {"GTX 260", CARD_NVIDIA_GEFORCE_GTX260}, /* Geforce 200 - midend */ + {"GTS 250", CARD_NVIDIA_GEFORCE_GTS250}, /* Geforce 200 - midend */ {"GT 240", CARD_NVIDIA_GEFORCE_GT240}, /* Geforce 200 - midend */ {"GT 220", CARD_NVIDIA_GEFORCE_GT220}, /* Geforce 200 - lowend */ {"GeForce 310", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ {"GeForce 305", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ {"GeForce 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ {"G 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */ - {"GTS 250", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ {"GTS 150", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ {"9800", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */ + {"9700M GT", CARD_NVIDIA_GEFORCE_9700MGT}, /* Geforce 9 - midend */ {"GT 140", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ {"9600", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */ {"GT 130", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */ @@ -1877,6 +2056,9 @@ cards_nvidia_binary[] = * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */ cards_amd_binary[] = { + {"RX 480", CARD_AMD_RADEON_RX_480}, + {"RX 460", CARD_AMD_RADEON_RX_460}, + {"R9 Fury Series", CARD_AMD_RADEON_R9_FURY}, /* Southern Islands */ {"HD 7900", CARD_AMD_RADEON_HD7900}, {"HD 7800", CARD_AMD_RADEON_HD7800}, @@ -1895,6 +2077,7 @@ cards_amd_binary[] = {"HD 6570", CARD_AMD_RADEON_HD6600}, {"HD 6500M", CARD_AMD_RADEON_HD6600M}, {"HD 6500", CARD_AMD_RADEON_HD6600}, + {"HD 6480G", CARD_AMD_RADEON_HD6480G}, {"HD 6400", CARD_AMD_RADEON_HD6400}, {"HD 6300", CARD_AMD_RADEON_HD6300}, {"HD 6200", CARD_AMD_RADEON_HD6300}, @@ -1965,12 +2148,24 @@ cards_amd_binary[] = }, cards_intel[] = { + /* Skylake */ + {"Iris Pro Graphics P580", CARD_INTEL_IPP580_1}, + {"Skylake", CARD_INTEL_HD520_1}, + /* Broadwell */ + {"Iris Pro P6300", CARD_INTEL_IPP6300}, + {"Iris Pro 6200", CARD_INTEL_IP6200}, + {"Iris 6100", CARD_INTEL_I6100}, + {"Iris(TM) Graphics 6100", CARD_INTEL_I6100}, /* MacOS */ /* Haswell */ + {"Iris Pro 5200", CARD_INTEL_IP5200_1}, + {"Iris 5100", CARD_INTEL_I5100_1}, {"Haswell Mobile", CARD_INTEL_HWM}, + {"Iris OpenGL Engine", CARD_INTEL_HWM}, /* MacOS */ /* Ivybridge */ {"Ivybridge Server", CARD_INTEL_IVBS}, {"Ivybridge Mobile", CARD_INTEL_IVBM}, {"Ivybridge Desktop", CARD_INTEL_IVBD}, + {"HD Graphics 4000", CARD_INTEL_IVBD}, /* MacOS */ /* Sandybridge */ {"Sandybridge Server", CARD_INTEL_SNBS}, {"Sandybridge Mobile", CARD_INTEL_SNBM}, @@ -2019,8 +2214,14 @@ cards_intel[] = * These are returned but not handled: RC410, RV380. */ cards_amd_mesa[] = { + /* Polaris 10/11 */ + {"POLARIS10", CARD_AMD_RADEON_RX_480}, + {"POLARIS11", CARD_AMD_RADEON_RX_460}, + /* Volcanic Islands */ + {"FIJI", CARD_AMD_RADEON_R9_FURY}, + {"TONGA", CARD_AMD_RADEON_R9_285}, /* Sea Islands */ - {"HAWAII", CARD_AMD_RADEON_R9 }, + {"HAWAII", CARD_AMD_RADEON_R9_290}, {"KAVERI", CARD_AMD_RADEON_R7 }, {"KABINI", CARD_AMD_RADEON_R3 }, {"BONAIRE", CARD_AMD_RADEON_HD8770}, @@ -2101,14 +2302,18 @@ cards_nvidia_mesa[] = { /* Maxwell */ {"NV124", CARD_NVIDIA_GEFORCE_GTX970}, + {"NV120", CARD_NVIDIA_GEFORCE_GTX980TI}, + {"NV118", CARD_NVIDIA_GEFORCE_840M}, {"NV117", CARD_NVIDIA_GEFORCE_GTX750}, /* Kepler */ + {"NV108", CARD_NVIDIA_GEFORCE_GT740M}, {"NVF1", CARD_NVIDIA_GEFORCE_GTX780TI}, {"NVF0", CARD_NVIDIA_GEFORCE_GTX780}, {"NVE6", CARD_NVIDIA_GEFORCE_GTX770M}, - {"NVE4", CARD_NVIDIA_GEFORCE_GTX680}, + {"NVE4", CARD_NVIDIA_GEFORCE_GTX680}, /* 690 / 675MX / 760TI */ /* Fermi */ {"NVD9", CARD_NVIDIA_GEFORCE_GT520}, + {"NVD7", CARD_NVIDIA_GEFORCE_820M}, {"NVCF", CARD_NVIDIA_GEFORCE_GTX550}, {"NVCE", CARD_NVIDIA_GEFORCE_GTX560}, {"NVC8", CARD_NVIDIA_GEFORCE_GTX570}, @@ -2378,7 +2583,7 @@ static enum wined3d_pci_device wined3d_guess_card(const struct shader_caps *shad static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info, const struct wined3d_shader_backend_ops *shader_backend_ops) { - if (shader_backend_ops == &glsl_shader_backend) + if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_VERTEX_SHADER]) return &glsl_vertex_pipe; return &ffp_vertex_pipe; } @@ -2386,9 +2591,9 @@ static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info, const struct wined3d_shader_backend_ops *shader_backend_ops) { - if (shader_backend_ops == &glsl_shader_backend) + if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_FRAGMENT_SHADER]) return &glsl_fragment_pipe; - if (shader_backend_ops == &arb_program_shader_backend && gl_info->supported[ARB_FRAGMENT_PROGRAM]) + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline; if (gl_info->supported[ATI_FRAGMENT_SHADER]) return &atifs_fragment_pipeline; @@ -2403,33 +2608,17 @@ static const struct wined3d_shader_backend_ops *select_shader_backend(const stru { BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); - if (glsl && gl_info->supported[ARB_FRAGMENT_SHADER]) + if (glsl && gl_info->supported[ARB_VERTEX_SHADER] && gl_info->supported[ARB_FRAGMENT_SHADER]) return &glsl_shader_backend; - if (glsl && gl_info->supported[ARB_VERTEX_SHADER]) - { - /* Geforce4 cards support GLSL but for vertex shaders only. Further - * its reported GLSL caps are wrong. This combined with the fact that - * GLSL won't offer more features or performance, use ARB shaders only - * on this card. */ - if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) - return &arb_program_shader_backend; + if (gl_info->supported[ARB_VERTEX_PROGRAM] && gl_info->supported[ARB_FRAGMENT_PROGRAM]) + return &arb_program_shader_backend; + if (glsl && (gl_info->supported[ARB_VERTEX_SHADER] || gl_info->supported[ARB_FRAGMENT_SHADER])) return &glsl_shader_backend; - } if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arb_program_shader_backend; return &none_shader_backend; } -static const struct blit_shader *select_blit_implementation(const struct wined3d_gl_info *gl_info, - const struct wined3d_shader_backend_ops *shader_backend_ops) -{ - if ((shader_backend_ops == &glsl_shader_backend - || shader_backend_ops == &arb_program_shader_backend) - && gl_info->supported[ARB_FRAGMENT_PROGRAM]) - return &arbfp_blit; - return &ffp_blit; -} - static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions, const struct wined3d_extension_map *map, UINT entry_count) { @@ -2471,7 +2660,7 @@ static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info, unsigned int i, j; GLint extensions_count; - glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); for (i = 0; i < extensions_count; ++i) { gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i)); @@ -2506,8 +2695,21 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) /* GL_ARB_blend_func_extended */ USE_GL_FUNC(glBindFragDataLocationIndexed) USE_GL_FUNC(glGetFragDataIndex) + /* GL_ARB_clear_buffer_object */ + USE_GL_FUNC(glClearBufferData) + USE_GL_FUNC(glClearBufferSubData) + /* GL_ARB_clear_texture */ + USE_GL_FUNC(glClearTexImage) + USE_GL_FUNC(glClearTexSubImage) + /* GL_ARB_clip_control */ + USE_GL_FUNC(glClipControl) /* GL_ARB_color_buffer_float */ USE_GL_FUNC(glClampColorARB) + /* GL_ARB_compute_shader */ + USE_GL_FUNC(glDispatchCompute) + USE_GL_FUNC(glDispatchComputeIndirect) + /* GL_ARB_copy_buffer */ + USE_GL_FUNC(glCopyBufferSubData) /* GL_ARB_debug_output */ USE_GL_FUNC(glDebugMessageCallbackARB) USE_GL_FUNC(glDebugMessageControlARB) @@ -2537,6 +2739,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glDeleteFramebuffers) USE_GL_FUNC(glDeleteRenderbuffers) USE_GL_FUNC(glFramebufferRenderbuffer) + USE_GL_FUNC(glFramebufferTexture) USE_GL_FUNC(glFramebufferTexture1D) USE_GL_FUNC(glFramebufferTexture2D) USE_GL_FUNC(glFramebufferTexture3D) @@ -2608,6 +2811,11 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glGetSamplerParameterfv) USE_GL_FUNC(glGetSamplerParameterIiv) USE_GL_FUNC(glGetSamplerParameterIuiv) + /* GL_ARB_shader_atomic_counters */ + USE_GL_FUNC(glGetActiveAtomicCounterBufferiv) + /* GL_ARB_shader_image_load_store */ + USE_GL_FUNC(glBindImageTexture) + USE_GL_FUNC(glMemoryBarrier) /* GL_ARB_shader_objects */ USE_GL_FUNC(glAttachObjectARB) USE_GL_FUNC(glBindAttribLocationARB) @@ -2650,6 +2858,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glUniformMatrix4fvARB) USE_GL_FUNC(glUseProgramObjectARB) USE_GL_FUNC(glValidateProgramARB) + /* GL_ARB_shader_storage_buffer_object */ + USE_GL_FUNC(glShaderStorageBlockBinding) /* GL_ARB_sync */ USE_GL_FUNC(glClientWaitSync) USE_GL_FUNC(glDeleteSync) @@ -2658,15 +2868,41 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glGetSynciv) USE_GL_FUNC(glIsSync) USE_GL_FUNC(glWaitSync) + /* GL_ARB_tessellation_shader */ + USE_GL_FUNC(glPatchParameteri) + USE_GL_FUNC(glPatchParameterfv) + /* GL_ARB_texture_buffer_object */ + USE_GL_FUNC(glTexBufferARB) + /* GL_ARB_texture_buffer_range */ + USE_GL_FUNC(glTexBufferRange) /* GL_ARB_texture_compression */ USE_GL_FUNC(glCompressedTexImage2DARB) USE_GL_FUNC(glCompressedTexImage3DARB) USE_GL_FUNC(glCompressedTexSubImage2DARB) USE_GL_FUNC(glCompressedTexSubImage3DARB) USE_GL_FUNC(glGetCompressedTexImageARB) + /* GL_ARB_texture_storage */ + USE_GL_FUNC(glTexStorage1D) + USE_GL_FUNC(glTexStorage2D) + USE_GL_FUNC(glTexStorage3D) + /* GL_ARB_texture_view */ + USE_GL_FUNC(glTextureView) /* GL_ARB_timer_query */ USE_GL_FUNC(glQueryCounter) USE_GL_FUNC(glGetQueryObjectui64v) + /* GL_ARB_transform_feedback2 */ + USE_GL_FUNC(glBindTransformFeedback); + USE_GL_FUNC(glDeleteTransformFeedbacks); + USE_GL_FUNC(glDrawTransformFeedback); + USE_GL_FUNC(glGenTransformFeedbacks); + USE_GL_FUNC(glIsTransformFeedback); + USE_GL_FUNC(glPauseTransformFeedback); + USE_GL_FUNC(glResumeTransformFeedback); + /* GL_ARB_transform_feedback3 */ + USE_GL_FUNC(glBeginQueryIndexed); + USE_GL_FUNC(glDrawTransformFeedbackStream); + USE_GL_FUNC(glEndQueryIndexed); + USE_GL_FUNC(glGetQueryIndexediv); /* GL_ARB_uniform_buffer_object */ USE_GL_FUNC(glBindBufferBase) USE_GL_FUNC(glBindBufferRange) @@ -2748,6 +2984,17 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glVertexAttrib4uivARB) USE_GL_FUNC(glVertexAttrib4usvARB) USE_GL_FUNC(glVertexAttribPointerARB) + /* GL_ARB_viewport_array */ + USE_GL_FUNC(glDepthRangeArrayv) + USE_GL_FUNC(glDepthRangeIndexed) + USE_GL_FUNC(glGetDoublei_v) + USE_GL_FUNC(glGetFloati_v) + USE_GL_FUNC(glScissorArrayv) + USE_GL_FUNC(glScissorIndexed) + USE_GL_FUNC(glScissorIndexedv) + USE_GL_FUNC(glViewportArrayv) + USE_GL_FUNC(glViewportIndexedf) + USE_GL_FUNC(glViewportIndexedfv) /* GL_ATI_fragment_shader */ USE_GL_FUNC(glAlphaFragmentOp1ATI) USE_GL_FUNC(glAlphaFragmentOp2ATI) @@ -2938,6 +3185,10 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(wglGetExtensionsStringARB) USE_GL_FUNC(wglGetPixelFormatAttribfvARB) USE_GL_FUNC(wglGetPixelFormatAttribivARB) + USE_GL_FUNC(wglQueryCurrentRendererIntegerWINE) + USE_GL_FUNC(wglQueryCurrentRendererStringWINE) + USE_GL_FUNC(wglQueryRendererIntegerWINE) + USE_GL_FUNC(wglQueryRendererStringWINE) USE_GL_FUNC(wglSetPixelFormatWINE) USE_GL_FUNC(wglSwapIntervalEXT) @@ -2945,8 +3196,10 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glActiveTexture) /* OpenGL 1.3 */ USE_GL_FUNC(glAttachShader) /* OpenGL 2.0 */ USE_GL_FUNC(glBeginQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glBeginTransformFeedback) /* OpenGL 3.0 */ USE_GL_FUNC(glBindAttribLocation) /* OpenGL 2.0 */ USE_GL_FUNC(glBindBuffer) /* OpenGL 1.5 */ + USE_GL_FUNC(glBindFragDataLocation) /* OpenGL 3.0 */ USE_GL_FUNC(glBindVertexArray) /* OpenGL 3.0 */ USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */ USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */ @@ -2971,21 +3224,27 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */ USE_GL_FUNC(glDeleteVertexArrays) /* OpenGL 3.0 */ USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDisablei) /* OpenGL 3.0 */ USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */ USE_GL_FUNC(glDrawArraysInstanced) /* OpenGL 3.1 */ USE_GL_FUNC(glDrawBuffers) /* OpenGL 2.0 */ USE_GL_FUNC(glDrawElementsInstanced) /* OpenGL 3.1 */ + USE_GL_FUNC(glEnablei) /* OpenGL 3.0 */ USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */ USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */ + USE_GL_FUNC(glEndTransformFeedback) /* OpenGL 3.0 */ + USE_GL_FUNC(glFramebufferTexture) /* OpenGL 3.2 */ USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */ USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */ USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */ USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */ USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */ USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetBooleani_v) /* OpenGL 3.0 */ USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */ USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */ USE_GL_FUNC(glGetDebugMessageLog) /* OpenGL 4.3 */ + USE_GL_FUNC(glGetIntegeri_v) /* OpenGL 3.0 */ USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */ USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */ @@ -2997,6 +3256,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glIsEnabledi) /* OpenGL 3.0 */ USE_GL_FUNC(glLinkProgram) /* OpenGL 2.0 */ USE_GL_FUNC(glMapBuffer) /* OpenGL 1.5 */ USE_GL_FUNC(glPointParameteri) /* OpenGL 1.4 */ @@ -3004,8 +3264,10 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glShaderSource) /* OpenGL 2.0 */ USE_GL_FUNC(glStencilFuncSeparate) /* OpenGL 2.0 */ USE_GL_FUNC(glStencilOpSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glTexBuffer) /* OpenGL 3.1 */ USE_GL_FUNC(glTexImage3D) /* OpenGL 1.2 */ USE_GL_FUNC(glTexSubImage3D) /* OpenGL 1.2 */ + USE_GL_FUNC(glTransformFeedbackVaryings)/* OpenGL 3.0 */ USE_GL_FUNC(glUniform1f) /* OpenGL 2.0 */ USE_GL_FUNC(glUniform1fv) /* OpenGL 2.0 */ USE_GL_FUNC(glUniform1i) /* OpenGL 2.0 */ @@ -3037,11 +3299,13 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glVertexAttrib4f) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4fv) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4Nsv) /* OpenGL 2.0 */ + USE_GL_FUNC(glVertexAttrib4Nub) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4Nubv) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4Nusv) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4sv) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttrib4ubv) /* OpenGL 2.0 */ USE_GL_FUNC(glVertexAttribDivisor) /* OpenGL 3.3 */ + USE_GL_FUNC(glVertexAttribIPointer) /* OpenGL 3.0 */ USE_GL_FUNC(glVertexAttribPointer) /* OpenGL 2.0 */ #undef USE_GL_FUNC @@ -3069,6 +3333,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB); MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB); MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB); + MAP_GL_FUNCTION(glBindFragDataLocation, glBindFragDataLocationEXT); MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT); MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT); MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT); @@ -3091,20 +3356,25 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB); MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB); MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB); + MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT); MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB); MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB); MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB); MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB); + MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT); MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB); MAP_GL_FUNCTION(glEndQuery, glEndQueryARB); + MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB); MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB); MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB); MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB); MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB); MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB); + MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT); MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB); MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB); MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB); + MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT); MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB); MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB); MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB); @@ -3115,9 +3385,11 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB); MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB); MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB); + MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT); MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); + MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB); MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT); MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT); MAP_GL_FUNCTION(glUniform1f, glUniform1fARB); @@ -3151,11 +3423,13 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB); MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB); MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB); + MAP_GL_FUNCTION(glVertexAttrib4Nub, glVertexAttrib4NubARB); MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB); MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB); MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB); MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB); MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB); + MAP_GL_FUNCTION(glVertexAttribIPointer, glVertexAttribIPointerEXT); MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB); #undef MAP_GL_FUNCTION #undef MAP_GL_FUNCTION_CAST @@ -3163,20 +3437,24 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) { + unsigned int i, sampler_count; GLfloat gl_floatv[2]; GLint gl_max; gl_info->limits.blends = 1; gl_info->limits.buffers = 1; - gl_info->limits.textures = 1; - gl_info->limits.texture_coords = 1; - gl_info->limits.vertex_uniform_blocks = 0; - gl_info->limits.geometry_uniform_blocks = 0; - gl_info->limits.fragment_uniform_blocks = 0; - gl_info->limits.fragment_samplers = 1; - gl_info->limits.vertex_samplers = 0; - gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers; + gl_info->limits.textures = 0; + gl_info->limits.texture_coords = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + gl_info->limits.uniform_blocks[i] = 0; + gl_info->limits.samplers[i] = 0; + } + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = 1; + gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; + gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; gl_info->limits.vertex_attribs = 16; + gl_info->limits.texture_buffer_offset_alignment = 1; gl_info->limits.glsl_vs_float_constants = 0; gl_info->limits.glsl_ps_float_constants = 0; gl_info->limits.arb_vs_float_constants = 0; @@ -3188,19 +3466,23 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) gl_info->limits.arb_ps_instructions = 0; gl_info->limits.arb_ps_temps = 0; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max); - gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max); + gl_info->limits.user_clip_distances = min(MAX_CLIP_DISTANCES, gl_max); TRACE("Clip plane support - max planes %d.\n", gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max); - gl_info->limits.lights = gl_max; - TRACE("Light support - max lights %d.\n", gl_max); + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max); + gl_info->limits.lights = gl_max; + TRACE("Light support - max lights %d.\n", gl_max); + } gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max); gl_info->limits.texture_size = gl_max; TRACE("Maximum texture size support - max texture size %d.\n", gl_max); - gl_info->gl_ops.gl.p_glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv); + gl_info->gl_ops.gl.p_glGetFloatv(gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + ? GL_ALIASED_POINT_SIZE_RANGE : GL_POINT_SIZE_RANGE, gl_floatv); gl_info->limits.pointsize_min = gl_floatv[0]; gl_info->limits.pointsize_max = gl_floatv[1]; TRACE("Maximum point size support - max point size %f.\n", gl_floatv[1]); @@ -3228,35 +3510,45 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) } if (gl_info->supported[ARB_MULTITEXTURE]) { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max); - gl_info->limits.textures = min(MAX_TEXTURES, gl_max); - TRACE("Max textures: %d.\n", gl_info->limits.textures); - - if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { - GLint tmp; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max); - gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max); - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp); - gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max); + gl_info->limits.textures = min(MAX_TEXTURES, gl_max); + TRACE("Max textures: %d.\n", gl_info->limits.textures); + + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max); + gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max); + } + else + { + gl_info->limits.texture_coords = gl_info->limits.textures; + } + TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords); + } + + if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_max; } else { - gl_info->limits.texture_coords = max(gl_info->limits.texture_coords, gl_max); - gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_info->limits.textures; } - TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords); - TRACE("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers); + TRACE("Max fragment samplers: %d.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]); if (gl_info->supported[ARB_VERTEX_SHADER]) { - GLint tmp; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp); - gl_info->limits.vertex_samplers = tmp; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp); - gl_info->limits.combined_samplers = tmp; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &tmp); - gl_info->limits.vertex_attribs = tmp; + unsigned int vertex_sampler_count; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &gl_max); + vertex_sampler_count = gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &gl_max); + gl_info->limits.combined_samplers = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &gl_max); + gl_info->limits.vertex_attribs = gl_max; /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup * is known at shader link time. In a vertex shader + pixel shader combination this isn't @@ -3272,25 +3564,33 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) * * So this is just a check to check that our assumption holds true. If not, write a warning * and reduce the number of vertex samplers or probably disable vertex texture fetch. */ - if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12 - && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers) + if (vertex_sampler_count && gl_info->limits.combined_samplers < 12 + && MAX_TEXTURES + vertex_sampler_count > gl_info->limits.combined_samplers) { FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n", - gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers); + vertex_sampler_count, gl_info->limits.combined_samplers); FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n"); if (gl_info->limits.combined_samplers > MAX_TEXTURES) - gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES; + vertex_sampler_count = gl_info->limits.combined_samplers - MAX_TEXTURES; else - gl_info->limits.vertex_samplers = 0; + vertex_sampler_count = 0; + gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = vertex_sampler_count; } } else { - gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers; + gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]; } - TRACE("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers); + TRACE("Max vertex samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]); TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers); + TRACE("Max vertex attributes: %u.\n", gl_info->limits.vertex_attribs); } + else + { + gl_info->limits.textures = 1; + gl_info->limits.texture_coords = 1; + } + if (gl_info->supported[ARB_VERTEX_BLEND]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max); @@ -3353,15 +3653,38 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.vertex_uniform_blocks = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max vertex uniform blocks: %u (%d).\n", gl_info->limits.vertex_uniform_blocks, gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max vertex uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max); } } - if (gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + if (gl_info->supported[ARB_TESSELLATION_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max hull uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL] = gl_max; + TRACE("Max hull samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL]); + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max domain uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN] = gl_max; + TRACE("Max domain samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN]); + } + if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.geometry_uniform_blocks = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max geometry uniform blocks: %u (%d).\n", gl_info->limits.geometry_uniform_blocks, gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max geometry uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY] = gl_max; + TRACE("Max geometry samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY]); } if (gl_info->supported[ARB_FRAGMENT_SHADER]) { @@ -3375,10 +3698,21 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_max); - gl_info->limits.fragment_uniform_blocks = min(gl_max, WINED3D_MAX_CBS); - TRACE("Max fragment uniform blocks: %u (%d).\n", gl_info->limits.fragment_uniform_blocks, gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max fragment uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL], gl_max); } } + if (gl_info->supported[ARB_COMPUTE_SHADER]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &gl_max); + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE] = min(gl_max, WINED3D_MAX_CBS); + TRACE("Max compute uniform blocks: %u (%d).\n", + gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE], gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &gl_max); + gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE] = gl_max; + TRACE("Max compute samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]); + } if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &gl_max); @@ -3386,22 +3720,75 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_max); TRACE("Max uniform buffer bindings: %d.\n", gl_max); } + if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_max); + gl_info->limits.texture_buffer_offset_alignment = gl_max; + TRACE("Minimum required texture buffer offset alignment %d.\n", gl_max); + } + if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS]) + { + GLint max_fragment_buffers, max_combined_buffers, max_bindings; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_fragment_buffers); + TRACE("Max fragment atomic counter buffers: %d.\n", max_fragment_buffers); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &max_combined_buffers); + TRACE("Max combined atomic counter buffers: %d.\n", max_combined_buffers); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings); + TRACE("Max atomic counter buffer bindings: %d.\n", max_bindings); + if (max_fragment_buffers < MAX_UNORDERED_ACCESS_VIEWS + || max_combined_buffers < MAX_UNORDERED_ACCESS_VIEWS + || max_bindings < MAX_UNORDERED_ACCESS_VIEWS) + { + WARN("Disabling ARB_shader_atomic_counters.\n"); + gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] = FALSE; + } + } + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_STREAMS, &gl_max); + TRACE("Max vertex streams: %d.\n", gl_max); + } if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess); else gl_info->limits.shininess = 128.0f; - if ((gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) - && wined3d_settings.allow_multisampling) + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) { gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max); gl_info->limits.samples = gl_max; } + + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = + min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS); + sampler_count = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + sampler_count += gl_info->limits.samplers[i]; + if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->limits.combined_samplers < sampler_count) + { + /* The minimum value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in OpenGL + * 3.2 is 48 (16 per stage). When tessellation shaders are supported + * the minimum value is increased to 80. */ + WARN("Graphics pipeline sampler count %u is greater than combined sampler count %u.\n", + sampler_count, gl_info->limits.combined_samplers); + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + gl_info->limits.samplers[i] = min(gl_info->limits.samplers[i], 16); + } + + /* A majority of OpenGL implementations allow us to statically partition + * the set of texture bindings into six separate sets. */ + gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers; + sampler_count = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + sampler_count += gl_info->limits.samplers[i]; + if (gl_info->limits.combined_samplers >= sampler_count) + gl_info->limits.graphics_samplers -= gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]; } /* Context activation is done by the caller. */ -static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD wined3d_creation_flags) +static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, + struct wined3d_caps_gl_ctx *caps_gl_ctx, DWORD wined3d_creation_flags) { static const struct { @@ -3447,7 +3834,10 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD {ARB_TEXTURE_FLOAT, MAKEDWORD_VERSION(3, 0)}, {ARB_TEXTURE_RG, MAKEDWORD_VERSION(3, 0)}, {EXT_DRAW_BUFFERS2, MAKEDWORD_VERSION(3, 0)}, + {EXT_PACKED_FLOAT, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_ARRAY, MAKEDWORD_VERSION(3, 0)}, {EXT_TEXTURE_INTEGER, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_SHARED_EXPONENT, MAKEDWORD_VERSION(3, 0)}, /* We don't want to enable EXT_GPU_SHADER4: even though similar * functionality is available in core GL 3.0 / GLSL 1.30, it's different * enough that reusing the same flag for the new features hurts more @@ -3456,7 +3846,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD * EXT_framebuffer_multisample and EXT_packed_depth_stencil * are integrated into ARB_framebuffer_object. */ + {ARB_COPY_BUFFER, MAKEDWORD_VERSION(3, 1)}, {ARB_DRAW_INSTANCED, MAKEDWORD_VERSION(3, 1)}, + {ARB_TEXTURE_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, {ARB_UNIFORM_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)}, {EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)}, /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */ @@ -3465,37 +3857,70 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2 * core geometry shaders so it's not really correct to expose the * extension for core-only support. */ + {ARB_FRAGMENT_COORD_CONVENTIONS, MAKEDWORD_VERSION(3, 2)}, {ARB_PROVOKING_VERTEX, MAKEDWORD_VERSION(3, 2)}, + {ARB_SEAMLESS_CUBE_MAP, MAKEDWORD_VERSION(3, 2)}, {ARB_SYNC, MAKEDWORD_VERSION(3, 2)}, {ARB_VERTEX_ARRAY_BGRA, MAKEDWORD_VERSION(3, 2)}, {ARB_BLEND_FUNC_EXTENDED, MAKEDWORD_VERSION(3, 3)}, + {ARB_EXPLICIT_ATTRIB_LOCATION, MAKEDWORD_VERSION(3, 3)}, {ARB_INSTANCED_ARRAYS, MAKEDWORD_VERSION(3, 3)}, {ARB_SAMPLER_OBJECTS, MAKEDWORD_VERSION(3, 3)}, {ARB_SHADER_BIT_ENCODING, MAKEDWORD_VERSION(3, 3)}, {ARB_TEXTURE_RGB10_A2UI, MAKEDWORD_VERSION(3, 3)}, + {ARB_TEXTURE_SWIZZLE, MAKEDWORD_VERSION(3, 3)}, {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)}, + {ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)}, + + {ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)}, + {ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)}, + {ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)}, + {ARB_TEXTURE_GATHER, MAKEDWORD_VERSION(4, 0)}, + {ARB_TRANSFORM_FEEDBACK2, MAKEDWORD_VERSION(4, 0)}, + {ARB_TRANSFORM_FEEDBACK3, MAKEDWORD_VERSION(4, 0)}, {ARB_ES2_COMPATIBILITY, MAKEDWORD_VERSION(4, 1)}, + {ARB_VIEWPORT_ARRAY, MAKEDWORD_VERSION(4, 1)}, {ARB_INTERNALFORMAT_QUERY, MAKEDWORD_VERSION(4, 2)}, {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADER_ATOMIC_COUNTERS, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADER_IMAGE_LOAD_STORE, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADING_LANGUAGE_420PACK, MAKEDWORD_VERSION(4, 2)}, + {ARB_SHADING_LANGUAGE_PACKING, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_COMPRESSION_BPTC, MAKEDWORD_VERSION(4, 2)}, + {ARB_TEXTURE_STORAGE, MAKEDWORD_VERSION(4, 2)}, + {ARB_CLEAR_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, + {ARB_COMPUTE_SHADER, MAKEDWORD_VERSION(4, 3)}, {ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)}, + {ARB_ES3_COMPATIBILITY, MAKEDWORD_VERSION(4, 3)}, + {ARB_FRAGMENT_LAYER_VIEWPORT, MAKEDWORD_VERSION(4, 3)}, {ARB_INTERNALFORMAT_QUERY2, MAKEDWORD_VERSION(4, 3)}, + {ARB_SHADER_IMAGE_SIZE, MAKEDWORD_VERSION(4, 3)}, + {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)}, + {ARB_STENCIL_TEXTURING, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_BUFFER_RANGE, MAKEDWORD_VERSION(4, 3)}, {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)}, + + {ARB_CLEAR_TEXTURE, MAKEDWORD_VERSION(4, 4)}, + + {ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)}, + {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, }; struct wined3d_driver_info *driver_info = &adapter->driver_info; const char *gl_vendor_str, *gl_renderer_str, *gl_version_str; struct wined3d_gl_info *gl_info = &adapter->gl_info; + const struct gpu_description *gpu_description; struct wined3d_vertex_caps vertex_caps; - enum wined3d_pci_vendor card_vendor; struct fragment_caps fragment_caps; struct shader_caps shader_caps; const char *WGL_Extensions = NULL; enum wined3d_gl_vendor gl_vendor; - enum wined3d_pci_device device; DWORD gl_version, gl_ext_emul_mask; + UINT64 vram_bytes = 0; HDC hdc; unsigned int i, j; GLint context_profile = 0; @@ -3535,7 +3960,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD if (gl_version >= MAKEDWORD_VERSION(3, 2)) { - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile); checkGLcall("Querying context profile"); } if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT) @@ -3600,6 +4025,13 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE; if (gl_version >= MAKEDWORD_VERSION(3, 2)) gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE; + if (gl_version >= MAKEDWORD_VERSION(4, 3)) + gl_info->supported[WINED3D_GL_VERSION_4_3] = TRUE; + + /* All the points are actually point sprites in core contexts, the APIs from + * ARB_point_sprite are not supported anymore. */ + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + gl_info->supported[ARB_POINT_SPRITE] = FALSE; if (gl_info->supported[APPLE_FENCE]) { @@ -3701,6 +4133,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode * we never render to sRGB surfaces). */ + TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n"); gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE; } if (gl_info->supported[ARB_OCCLUSION_QUERY]) @@ -3721,6 +4154,48 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD if (!counter_bits) gl_info->supported[ARB_TIMER_QUERY] = FALSE; } + if (gl_version >= MAKEDWORD_VERSION(3, 0)) + { + GLint counter_bits; + + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = TRUE; + + GL_EXTCALL(glGetQueryiv(GL_PRIMITIVES_GENERATED, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Primitives query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; + + GL_EXTCALL(glGetQueryiv(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_QUERY_COUNTER_BITS, &counter_bits)); + TRACE("Transform feedback primitives query counter has %d bits.\n", counter_bits); + if (!counter_bits) + gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE; + } + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + GLint subpixel_bits; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits); + TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits); + if (subpixel_bits < 8 && gl_info->supported[ARB_CLIP_CONTROL]) + { + TRACE("Disabling ARB_clip_control because viewport subpixel bits < 8.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } + } + if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + /* When using ARB_clip_control we need the float viewport parameters + * introduced by ARB_viewport_array to take care of the shifted pixel + * coordinates. */ + TRACE("Disabling ARB_clip_control because ARB_viewport_array is not supported.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } + if (gl_info->supported[ARB_STENCIL_TEXTURING] && !gl_info->supported[ARB_TEXTURE_SWIZZLE]) + { + /* The stencil value needs to be placed in the green channel. */ + TRACE("Disabling ARB_stencil_texturing because ARB_texture_swizzle is not supported.\n"); + gl_info->supported[ARB_STENCIL_TEXTURING] = FALSE; + } if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP]) { TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n"); @@ -3731,6 +4206,12 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD TRACE(" IMPLIED: ARB_texture_mirror_clamp_to_edge support (by ATI_texture_mirror_once).\n"); gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] = TRUE; } + if (gl_info->supported[ARB_TEXTURE_STORAGE] && gl_info->supported[APPLE_YCBCR_422]) + { + /* AFAIK APPLE_ycbcr_422 is only available in legacy contexts so we shouldn't ever hit this. */ + FIXME("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n"); + gl_info->supported[APPLE_YCBCR_422] = FALSE; + } wined3d_adapter_init_limits(gl_info); @@ -3747,6 +4228,8 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */ sscanf(str, "%u.%u", &major, &minor); gl_info->glsl_version = MAKEDWORD_VERSION(major, minor); + if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)) + gl_info->supported[WINED3D_GLSL_130] = TRUE; } checkGLcall("extension detection"); @@ -3754,21 +4237,25 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD adapter->shader_backend = select_shader_backend(gl_info); adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend); adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend); - adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend); adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING; adapter->d3d_info.limits.vs_version = shader_caps.vs_version; + adapter->d3d_info.limits.hs_version = shader_caps.hs_version; + adapter->d3d_info.limits.ds_version = shader_caps.ds_version; adapter->d3d_info.limits.gs_version = shader_caps.gs_version; adapter->d3d_info.limits.ps_version = shader_caps.ps_version; + adapter->d3d_info.limits.cs_version = shader_caps.cs_version; adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count; adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count; adapter->d3d_info.limits.varying_count = shader_caps.varying_count; + adapter->d3d_info.shader_double_precision = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION; adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps); adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw; adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes; adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices; + adapter->d3d_info.limits.active_light_count = vertex_caps.max_active_lights; adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading; adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); @@ -3778,6 +4265,17 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags; TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages); + adapter->d3d_info.valid_rt_mask = 0; + for (i = 0; i < gl_info->limits.buffers; ++i) + adapter->d3d_info.valid_rt_mask |= (1u << i); + + if (!adapter->d3d_info.shader_color_key) + { + /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */ + WARN("Disabling ARB_texture_storage because fragment pipe doesn't support color keying.\n"); + gl_info->supported[ARB_TEXTURE_STORAGE] = FALSE; + } + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) { gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbuffer; @@ -3795,11 +4293,13 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D; gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D; gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D; + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer; gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer; gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv; gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer; gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap; + gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture; } else { @@ -3829,6 +4329,12 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n"); wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; } + + if (gl_info->supported[ARB_GEOMETRY_SHADER4]) + { + gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB; + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB; + } if (gl_info->supported[EXT_FRAMEBUFFER_BLIT]) { gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT; @@ -3840,13 +4346,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD } } - gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str); - card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str); - TRACE("Found GL_VENDOR (%s)->(0x%04x/0x%04x).\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor); - - device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version, gl_renderer_str, &gl_vendor, &card_vendor); - TRACE("Found (fake) card: 0x%x (vendor id), 0x%x (device id).\n", card_vendor, device); - gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT; gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] = gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT; @@ -3856,10 +4355,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] = gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT; - adapter->d3d_info.valid_rt_mask = 0; - for (i = 0; i < gl_info->limits.buffers; ++i) - adapter->d3d_info.valid_rt_mask |= (1u << i); - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { GLuint vao; @@ -3869,8 +4364,31 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD checkGLcall("creating VAO"); } - fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device); - init_driver_info(gl_info, driver_info, card_vendor, device); + gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str); + TRACE("Guessed GL vendor %#x.\n", gl_vendor); + + if (!(gpu_description = query_gpu_description(gl_info, &vram_bytes))) + { + enum wined3d_pci_vendor vendor; + enum wined3d_pci_device device; + + vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str); + TRACE("Guessed vendor PCI ID 0x%04x.\n", vendor); + + device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version, + gl_renderer_str, &gl_vendor, &vendor); + TRACE("Guessed device PCI ID 0x%04x.\n", device); + + if (!(gpu_description = get_gpu_description(vendor, device))) + { + ERR("Card %04x:%04x not found in driver DB.\n", vendor, device); + return FALSE; + } + } + fixup_extensions(gl_info, caps_gl_ctx, gl_renderer_str, gl_vendor, + gpu_description->vendor, gpu_description->card); + init_driver_info(driver_info, gpu_description, vram_bytes); + gl_ext_emul_mask = adapter->vertex_pipe->vp_get_emul_mask(gl_info) | adapter->fragment_pipe->get_emul_mask(gl_info); if (gl_ext_emul_mask & GL_EXT_EMUL_ARB_MULTITEXTURE) @@ -3950,7 +4468,7 @@ UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT ad return 0; adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, format_id); + format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET); format_bits = format->byte_count * CHAR_BIT; memset(&mode, 0, sizeof(mode)); @@ -4004,7 +4522,7 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada return WINED3DERR_INVALIDCALL; adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, format_id); + format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET); format_bits = format->byte_count * CHAR_BIT; memset(&m, 0, sizeof(m)); @@ -4064,6 +4582,106 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada return WINED3D_OK; } +HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d, + unsigned int adapter_idx, struct wined3d_display_mode *mode) +{ + unsigned int i, j, mode_count, matching_mode_count, closest; + struct wined3d_display_mode **matching_modes; + struct wined3d_display_mode *modes; + HRESULT hr; + + TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode); + + if (!(mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx, + mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN))) + { + WARN("Adapter has 0 matching modes.\n"); + return E_FAIL; + } + + if (!(modes = wined3d_calloc(mode_count, sizeof(*modes)))) + return E_OUTOFMEMORY; + if (!(matching_modes = wined3d_calloc(mode_count, sizeof(*matching_modes)))) + { + HeapFree(GetProcessHeap(), 0, modes); + return E_OUTOFMEMORY; + } + + for (i = 0; i < mode_count; ++i) + { + if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx, + mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i]))) + { + HeapFree(GetProcessHeap(), 0, matching_modes); + HeapFree(GetProcessHeap(), 0, modes); + return hr; + } + matching_modes[i] = &modes[i]; + } + + matching_mode_count = mode_count; + + if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN) + { + for (i = 0, j = 0; i < matching_mode_count; ++i) + { + if (matching_modes[i]->scanline_ordering == mode->scanline_ordering) + matching_modes[j++] = matching_modes[i]; + } + if (j > 0) + matching_mode_count = j; + } + + if (mode->refresh_rate) + { + for (i = 0, j = 0; i < matching_mode_count; ++i) + { + if (matching_modes[i]->refresh_rate == mode->refresh_rate) + matching_modes[j++] = matching_modes[i]; + } + if (j > 0) + matching_mode_count = j; + } + + if (!mode->width || !mode->height) + { + struct wined3d_display_mode current_mode; + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, + ¤t_mode, NULL))) + { + HeapFree(GetProcessHeap(), 0, matching_modes); + HeapFree(GetProcessHeap(), 0, modes); + return hr; + } + mode->width = current_mode.width; + mode->height = current_mode.height; + } + + closest = ~0u; + for (i = 0, j = 0; i < matching_mode_count; ++i) + { + unsigned int d = abs(mode->width - matching_modes[i]->width) + + abs(mode->height - matching_modes[i]->height); + + if (closest > d) + { + closest = d; + j = i; + } + } + + *mode = *matching_modes[j]; + + HeapFree(GetProcessHeap(), 0, matching_modes); + HeapFree(GetProcessHeap(), 0, modes); + + TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height, + mode->refresh_rate, debug_d3dformat(mode->format_id), + mode->scanline_ordering); + + return WINED3D_OK; +} + HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation) { @@ -4163,7 +4781,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id), mode->scanline_ordering); - format = wined3d_get_format(&adapter->gl_info, mode->format_id); + format = wined3d_get_format(&adapter->gl_info, mode->format_id, WINED3DUSAGE_RENDERTARGET); new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT; @@ -4206,6 +4824,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, || !(new_mode.dmFields & DM_DISPLAYFLAGS))) { TRACE("Skipping redundant mode setting call.\n"); + adapter->screen_format = new_format_id; return WINED3D_OK; } @@ -4370,7 +4989,7 @@ static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_in lockable = TRUE; /* On some modern cards like the Geforce8/9, GLX doesn't offer some - * dephth/stencil formats which D3D9 reports. We can safely report + * depth/stencil formats which D3D9 reports. We can safely report * "compatible" formats (e.g. D24 can be used for D16) as long as we * aren't dealing with a lockable format. This also helps D3D <= 7 as they * expect D16 which isn't offered without this on Geforce8 cards. */ @@ -4404,8 +5023,8 @@ HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d, return WINED3DERR_INVALIDCALL; adapter = &wined3d->adapters[adapter_idx]; - rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id); - ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id); + rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id, WINED3DUSAGE_RENDERTARGET); + ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id, WINED3DUSAGE_DEPTHSTENCIL); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { if ((rt_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET) @@ -4446,7 +5065,7 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 enum wined3d_multisample_type multisample_type, DWORD *quality_levels) { const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id); + const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id, 0); HRESULT hr = WINED3D_OK; TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, " @@ -4574,13 +5193,11 @@ static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckSurfaceCapability(const struct wined3d_adapter *adapter, - const struct wined3d_format *adapter_format, - const struct wined3d_format *check_format, BOOL no3d) +static BOOL wined3d_check_surface_capability(const struct wined3d_format *format, BOOL no3d) { if (no3d) { - switch (check_format->id) + switch (format->id) { case WINED3DFMT_B8G8R8_UNORM: TRACE("[FAILED] - Not enumerated on Windows.\n"); @@ -4610,21 +5227,7 @@ static BOOL CheckSurfaceCapability(const struct wined3d_adapter *adapter, } } - /* All formats that are supported for textures are supported for surfaces - * as well. */ - if (check_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) - return TRUE; - /* All depth stencil formats are supported on surfaces */ - if (CheckDepthStencilCapability(adapter, adapter_format, check_format, WINED3D_GL_RES_TYPE_TEX_2D)) - return TRUE; - if (CheckDepthStencilCapability(adapter, adapter_format, check_format, WINED3D_GL_RES_TYPE_RB)) - return TRUE; - - /* If opengl can't process the format natively, the blitter may be able to convert it */ - if (adapter->blitter->blit_supported(&adapter->gl_info, &adapter->d3d_info, - WINED3D_BLIT_OP_COLOR_BLIT, - NULL, WINED3D_POOL_DEFAULT, 0, check_format, - NULL, WINED3D_POOL_DEFAULT, 0, adapter_format)) + if (format->glInternal) { TRACE("[OK]\n"); return TRUE; @@ -4649,13 +5252,14 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad { const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx]; const struct wined3d_gl_info *gl_info = &adapter->gl_info; - const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id); - const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id); + const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id, + WINED3DUSAGE_RENDERTARGET); + const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id, usage); DWORD format_flags = 0; DWORD allowed_usage; enum wined3d_gl_resource_type gl_type; - TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s,\n" + TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s, " "resource_type %s, check_format %s.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id), debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type), @@ -4666,32 +5270,30 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad switch (resource_type) { - case WINED3D_RTYPE_SURFACE: - if (!CheckSurfaceCapability(adapter, adapter_format, format, wined3d->flags & WINED3D_NO3D)) - { - TRACE("[FAILED] - Not supported for plain surfaces.\n"); - return WINED3DERR_NOTAVAILABLE; - } - + case WINED3D_RTYPE_TEXTURE_2D: allowed_usage = WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; if (usage & WINED3DUSAGE_RENDERTARGET) allowed_usage |= WINED3DUSAGE_QUERY_SRGBWRITE; - gl_type = WINED3D_GL_RES_TYPE_RB; - break; + if (!(usage & WINED3DUSAGE_TEXTURE)) + { + if (!wined3d_check_surface_capability(format, wined3d->flags & WINED3D_NO3D)) + { + TRACE("[FAILED] - Not supported for plain surfaces.\n"); + return WINED3DERR_NOTAVAILABLE; + } - case WINED3D_RTYPE_TEXTURE_2D: - format_flags |= WINED3DFMT_FLAG_TEXTURE; - allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP - | WINED3DUSAGE_DEPTHSTENCIL + gl_type = WINED3D_GL_RES_TYPE_RB; + break; + } + allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_LEGACY_CUBEMAP - | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_SOFTWAREPROCESSING + | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER | WINED3DUSAGE_QUERY_LEGACYBUMPMAP - | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE | WINED3DUSAGE_QUERY_VERTEXTEXTURE @@ -4712,10 +5314,9 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad break; case WINED3D_RTYPE_TEXTURE_3D: - case WINED3D_RTYPE_VOLUME: - format_flags |= WINED3DFMT_FLAG_TEXTURE; allowed_usage = WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_SOFTWAREPROCESSING + | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING | WINED3DUSAGE_QUERY_SRGBREAD @@ -4737,6 +5338,8 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; } + if (usage & WINED3DUSAGE_TEXTURE) + format_flags |= WINED3DFMT_FLAG_TEXTURE; if (usage & WINED3DUSAGE_QUERY_FILTER) format_flags |= WINED3DFMT_FLAG_FILTERING; if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) @@ -4792,9 +5395,7 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad enum wined3d_format_id format_id, UINT width) { const struct wined3d_gl_info *gl_info; -#if !defined(STAGING_CSMT) unsigned int row_pitch, slice_pitch; -#endif /* STAGING_CSMT */ TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n", wined3d, adapter_idx, debug_d3dformat(format_id), width); @@ -4803,14 +5404,10 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad return ~0u; gl_info = &wined3d->adapters[adapter_idx].gl_info; -#if defined(STAGING_CSMT) - return wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id), width); -#else /* STAGING_CSMT */ - wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id), + wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id, 0), 1, width, 1, &row_pitch, &slice_pitch); return row_pitch; -#endif /* STAGING_CSMT */ } HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx, @@ -4927,7 +5524,7 @@ HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adap /* Validate that the back buffer format is usable for render targets. */ if (FAILED(wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format, - WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_SURFACE, backbuffer_format))) + WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_TEXTURE_2D, backbuffer_format))) { TRACE("Format %s not allowed for render targets.\n", debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; @@ -4940,11 +5537,12 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte enum wined3d_device_type device_type, WINED3DCAPS *caps) { const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx]; + const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; const struct wined3d_gl_info *gl_info = &adapter->gl_info; - struct shader_caps shader_caps; - struct fragment_caps fragment_caps; struct wined3d_vertex_caps vertex_caps; DWORD ckey_caps, blit_caps, fx_caps; + struct fragment_caps fragment_caps; + struct shader_caps shader_caps; TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps); @@ -5469,8 +6067,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINEDDCAPS_CANCLIP | WINEDDCAPS_CANCLIPSTRETCHED | WINEDDCAPS_COLORKEY | - WINEDDCAPS_COLORKEYHWASSIST | - WINEDDCAPS_ALIGNBOUNDARYSRC; + WINEDDCAPS_COLORKEYHWASSIST; /* Fill the ddraw caps structure */ caps->ddraw_caps.caps = WINEDDCAPS_GDI | @@ -5513,6 +6110,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->ddraw_caps.caps |= WINEDDCAPS_3D; } + caps->shader_double_precision = d3d_info->shader_double_precision; + return WINED3D_OK; } @@ -5554,30 +6153,30 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, e static void WINE_GLAPI invalid_func(const void *data) { - ERR("Invalid vertex attribute function called\n"); + ERR("Invalid vertex attribute function called.\n"); DebugBreak(); } static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data) { - ERR("Invalid texcoord function called\n"); + ERR("Invalid texcoord function called.\n"); DebugBreak(); } -#if defined(STAGING_CSMT) -/* Helper functions for providing vertex data to opengl. The arrays are initialized based on - * the extension detection and are used in draw_strided_slow - */ -#else /* STAGING_CSMT */ -/* Helper functions for providing vertex data to opengl. The arrays are initialized based on - * the extension detection and are used in drawStridedSlow - */ -#endif /* STAGING_CSMT */ +static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data) +{ + ERR("Invalid attribute function called.\n"); + DebugBreak(); +} + +/* Helper functions for providing vertex data to OpenGL. The arrays are + * initialised based on the extension detection and are used in + * draw_primitive_immediate_mode(). */ static void WINE_GLAPI position_d3dcolor(const void *data) { DWORD pos = *((const DWORD *)data); - FIXME("Add a test for fixed function position from d3dcolor type\n"); + FIXME("Add a test for fixed function position from d3dcolor type.\n"); context_get_current()->gl_info->gl_ops.gl.p_glVertex4s(D3DCOLOR_B_R(pos), D3DCOLOR_B_G(pos), D3DCOLOR_B_B(pos), @@ -5625,7 +6224,48 @@ static void WINE_GLAPI specular_d3dcolor(const void *data) static void WINE_GLAPI warn_no_specular_func(const void *data) { - WARN("GL_EXT_secondary_color not supported\n"); + WARN("GL_EXT_secondary_color not supported.\n"); +} + +static void WINE_GLAPI generic_d3dcolor(GLuint idx, const void *data) +{ + DWORD color = *((const DWORD *)data); + + context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nub(idx, + D3DCOLOR_B_R(color), D3DCOLOR_B_G(color), + D3DCOLOR_B_B(color), D3DCOLOR_B_A(color)); +} + +static void WINE_GLAPI generic_short2n(GLuint idx, const void *data) +{ + const GLshort s[] = {((const GLshort *)data)[0], ((const GLshort *)data)[1], 0, 1}; + + context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nsv(idx, s); +} + +static void WINE_GLAPI generic_ushort2n(GLuint idx, const void *data) +{ + const GLushort s[] = {((const GLushort *)data)[0], ((const GLushort *)data)[1], 0, 1}; + + context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nusv(idx, s); +} + +static void WINE_GLAPI generic_float16_2(GLuint idx, const void *data) +{ + float x = float_16_to_32(((const unsigned short *)data) + 0); + float y = float_16_to_32(((const unsigned short *)data) + 1); + + context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib2f(idx, x, y); +} + +static void WINE_GLAPI generic_float16_4(GLuint idx, const void *data) +{ + float x = float_16_to_32(((const unsigned short *)data) + 0); + float y = float_16_to_32(((const unsigned short *)data) + 1); + float z = float_16_to_32(((const unsigned short *)data) + 2); + float w = float_16_to_32(((const unsigned short *)data) + 3); + + context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4f(idx, x, y, z, w); } static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter) @@ -5633,112 +6273,56 @@ static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter) const struct wined3d_gl_info *gl_info = &adapter->gl_info; struct wined3d_d3d_info *d3d_info = &adapter->d3d_info; struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops; + unsigned int i; + + for (i = 0; i < WINED3D_FFP_EMIT_COUNT; ++i) + { + ops->position[i] = invalid_func; + ops->diffuse[i] = invalid_func; + ops->specular[i] = invalid_func; + ops->normal[i] = invalid_func; + ops->texcoord[i] = invalid_texcoord_func; + ops->generic[i] = invalid_generic_attrib_func; + } - ops->position[WINED3D_FFP_EMIT_FLOAT1] = invalid_func; - ops->position[WINED3D_FFP_EMIT_FLOAT2] = invalid_func; ops->position[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv; if (!d3d_info->xyzrhw) ops->position[WINED3D_FFP_EMIT_FLOAT4] = position_float4; else ops->position[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex4fv; ops->position[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor; - ops->position[WINED3D_FFP_EMIT_UBYTE4] = invalid_func; - ops->position[WINED3D_FFP_EMIT_SHORT2] = invalid_func; ops->position[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex2sv; - ops->position[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_SHORT2N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_SHORT4N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_USHORT2N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_USHORT4N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_UDEC3] = invalid_func; - ops->position[WINED3D_FFP_EMIT_DEC3N] = invalid_func; - ops->position[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func; - ops->position[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func; - ops->position[WINED3D_FFP_EMIT_INVALID] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_FLOAT1] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_FLOAT2] = invalid_func; ops->diffuse[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor3fv; ops->diffuse[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4fv; ops->diffuse[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor; - ops->diffuse[WINED3D_FFP_EMIT_UBYTE4] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_SHORT2] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_SHORT4] = invalid_func; ops->diffuse[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4ubv; - ops->diffuse[WINED3D_FFP_EMIT_SHORT2N] = invalid_func; ops->diffuse[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4sv; - ops->diffuse[WINED3D_FFP_EMIT_USHORT2N] = invalid_func; ops->diffuse[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4usv; - ops->diffuse[WINED3D_FFP_EMIT_UDEC3] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_DEC3N] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func; - ops->diffuse[WINED3D_FFP_EMIT_INVALID] = invalid_func; /* No 4 component entry points here. */ - ops->specular[WINED3D_FFP_EMIT_FLOAT1] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_FLOAT2] = invalid_func; if (gl_info->supported[EXT_SECONDARY_COLOR]) ops->specular[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT); else ops->specular[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func; - ops->specular[WINED3D_FFP_EMIT_FLOAT4] = invalid_func; if (gl_info->supported[EXT_SECONDARY_COLOR]) ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor; else ops->specular[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func; - ops->specular[WINED3D_FFP_EMIT_UBYTE4] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_SHORT2] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_SHORT4] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_SHORT2N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_SHORT4N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_USHORT2N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_USHORT4N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_UDEC3] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_DEC3N] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func; - ops->specular[WINED3D_FFP_EMIT_INVALID] = invalid_func; /* Only 3 component entry points here. Test how others behave. Float4 * normals are used by one of our tests, trying to pass it to the pixel * shader, which fails on Windows. */ - ops->normal[WINED3D_FFP_EMIT_FLOAT1] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_FLOAT2] = invalid_func; ops->normal[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; /* Just ignore the 4th value. */ ops->normal[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv; - ops->normal[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_UBYTE4] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_SHORT2] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_SHORT4] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_SHORT2N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_SHORT4N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_USHORT2N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_USHORT4N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_UDEC3] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_DEC3N] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func; - ops->normal[WINED3D_FFP_EMIT_INVALID] = invalid_func; ops->texcoord[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB; ops->texcoord[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB; ops->texcoord[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB; ops->texcoord[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB; - ops->texcoord[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func; ops->texcoord[WINED3D_FFP_EMIT_SHORT2] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2svARB; ops->texcoord[WINED3D_FFP_EMIT_SHORT4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4svARB; - ops->texcoord[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func; if (gl_info->supported[NV_HALF_FLOAT]) { /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT. */ @@ -5747,12 +6331,36 @@ static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter) ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4hvNV; } + + ops->generic[WINED3D_FFP_EMIT_FLOAT1] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib1fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT3] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib3fv; + ops->generic[WINED3D_FFP_EMIT_FLOAT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4fv; + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) + ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = generic_d3dcolor; + else + ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; + ops->generic[WINED3D_FFP_EMIT_UBYTE4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4ubv; + ops->generic[WINED3D_FFP_EMIT_SHORT2] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2sv; + ops->generic[WINED3D_FFP_EMIT_SHORT4] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4sv; + ops->generic[WINED3D_FFP_EMIT_UBYTE4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv; + ops->generic[WINED3D_FFP_EMIT_SHORT2N] = generic_short2n; + ops->generic[WINED3D_FFP_EMIT_SHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nsv; + ops->generic[WINED3D_FFP_EMIT_USHORT2N] = generic_ushort2n; + ops->generic[WINED3D_FFP_EMIT_USHORT4N] = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nusv; + if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) + { + ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2hvNV; + ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = + (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4hvNV; + } else { - ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func; - ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func; + ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = generic_float16_2; + ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = generic_float16_4; } - ops->texcoord[WINED3D_FFP_EMIT_INVALID] = invalid_texcoord_func; } static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc) @@ -5771,7 +6379,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc attribute = WGL_NUMBER_PIXEL_FORMATS_ARB; GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count)); - adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cfg_count * sizeof(*adapter->cfgs)); + adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs)); attribs[attrib_count++] = WGL_RED_BITS_ARB; attribs[attrib_count++] = WGL_GREEN_BITS_ARB; attribs[attrib_count++] = WGL_BLUE_BITS_ARB; @@ -5836,7 +6444,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc int cfg_count; cfg_count = DescribePixelFormat(dc, 0, 0, 0); - adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cfg_count * sizeof(*adapter->cfgs)); + adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs)); for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i) { @@ -5906,6 +6514,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, ALL_WGL_FUNCS #undef USE_GL_FUNC gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers"); + gl_info->gl_ops.wgl.p_wglGetPixelFormat = (void *)GetProcAddress(mod_gl, "wglGetPixelFormat"); } #else /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */ @@ -5959,13 +6568,17 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff); } - if (!wined3d_adapter_init_gl_caps(adapter, wined3d_creation_flags)) + if (!wined3d_adapter_init_gl_caps(adapter, &caps_gl_ctx, wined3d_creation_flags)) { ERR("Failed to initialize GL caps for adapter %p.\n", adapter); wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); return FALSE; } + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + ERR_(winediag)("You are using the backbuffer for offscreen rendering. " + "This is unsupported, and will be removed in a future version.\n"); + wined3d_adapter_init_fb_cfgs(adapter, caps_gl_ctx.dc); /* We haven't found any suitable formats. This should only happen in * case of GDI software rendering, which is pretty useless anyway. */ @@ -6005,7 +6618,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, return TRUE; } -static void wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal) +static BOOL wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal) { DISPLAY_DEVICEW display_device; @@ -6019,17 +6632,19 @@ static void wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordi else adapter->vram_bytes = 128 * 1024 * 1024; - initPixelFormatsNoGL(&adapter->gl_info); + if (!wined3d_adapter_init_format_info(adapter, NULL)) + return FALSE; adapter->vertex_pipe = &none_vertex_pipe; adapter->fragment_pipe = &none_fragment_pipe; adapter->shader_backend = &none_shader_backend; - adapter->blitter = &cpu_blit; display_device.cb = sizeof(display_device); EnumDisplayDevicesW(NULL, ordinal, &display_device, 0); TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName)); strcpyW(adapter->DeviceName, display_device.DeviceName); + + return TRUE; } static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {} @@ -6041,19 +6656,18 @@ const struct wined3d_parent_ops wined3d_null_parent_ops = HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) { + BOOL ret; + wined3d->ref = 1; wined3d->flags = flags; TRACE("Initializing adapters.\n"); if (flags & WINED3D_NO3D) - { - wined3d_adapter_init_nogl(&wined3d->adapters[0], 0); - wined3d->adapter_count = 1; - return WINED3D_OK; - } - - if (!wined3d_adapter_init(&wined3d->adapters[0], 0, flags)) + ret = wined3d_adapter_init_nogl(&wined3d->adapters[0], 0); + else + ret = wined3d_adapter_init(&wined3d->adapters[0], 0, flags); + if (!ret) { WARN("Failed to initialize adapter.\n"); return E_FAIL; diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index 4e77868adb8..cd7dcab0de5 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -28,145 +28,215 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); +WINE_DECLARE_DEBUG_CHANNEL(d3d); /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -static void draw_strided_fast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, -#else /* STAGING_CSMT */ -static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, -#endif /* STAGING_CSMT */ - const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) +static void draw_primitive_arrays(struct wined3d_context *context, const struct wined3d_state *state, + const void *idx_data, unsigned int idx_size, int base_vertex_idx, unsigned int start_idx, + unsigned int count, unsigned int start_instance, unsigned int instance_count) { - if (idx_size) + const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops; + GLenum idx_type = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; + const struct wined3d_stream_info *si = &context->stream_info; + unsigned int instanced_elements[ARRAY_SIZE(si->elements)]; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int instanced_element_count = 0; + unsigned int i, j; + + if (!instance_count) { - GLenum idxtype = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; - if (instance_count) + if (!idx_size) { - if (start_instance) - FIXME("Start instance (%u) not supported.\n", start_instance); - if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) - { - GL_EXTCALL(glDrawElementsInstancedBaseVertex(primitive_type, count, idxtype, - (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_index)); - checkGLcall("glDrawElementsInstancedBaseVertex"); - } - else - { - GL_EXTCALL(glDrawElementsInstanced(primitive_type, count, idxtype, - (const char *)idx_data + (idx_size * start_idx), instance_count)); - checkGLcall("glDrawElementsInstanced"); - } + gl_info->gl_ops.gl.p_glDrawArrays(state->gl_primitive_type, start_idx, count); + checkGLcall("glDrawArrays"); + return; } - else if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + + if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) { - GL_EXTCALL(glDrawElementsBaseVertex(primitive_type, count, idxtype, - (const char *)idx_data + (idx_size * start_idx), base_vertex_index)); + GL_EXTCALL(glDrawElementsBaseVertex(state->gl_primitive_type, count, idx_type, + (const char *)idx_data + (idx_size * start_idx), base_vertex_idx)); + checkGLcall("glDrawElementsBaseVertex"); + return; + } + + gl_info->gl_ops.gl.p_glDrawElements(state->gl_primitive_type, count, + idx_type, (const char *)idx_data + (idx_size * start_idx)); + checkGLcall("glDrawElements"); + return; + } + + if (start_instance) + FIXME("Start instance (%u) not supported.\n", start_instance); + + if (gl_info->supported[ARB_INSTANCED_ARRAYS]) + { + if (!idx_size) + { + GL_EXTCALL(glDrawArraysInstanced(state->gl_primitive_type, start_idx, count, instance_count)); + checkGLcall("glDrawArraysInstanced"); + return; + } + + if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + { + GL_EXTCALL(glDrawElementsInstancedBaseVertex(state->gl_primitive_type, count, idx_type, + (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_idx)); + checkGLcall("glDrawElementsInstancedBaseVertex"); + return; + } + + GL_EXTCALL(glDrawElementsInstanced(state->gl_primitive_type, count, idx_type, + (const char *)idx_data + (idx_size * start_idx), instance_count)); + checkGLcall("glDrawElementsInstanced"); + return; + } + + /* Instancing emulation by mixing immediate mode and arrays. */ + + /* This is a nasty thing. MSDN says no hardware supports this and + * applications have to use software vertex processing. We don't support + * this for now. + * + * Shouldn't be too hard to support with OpenGL, in theory just call + * glDrawArrays() instead of drawElements(). But the stream fequency value + * has a different meaning in that situation. */ + if (!idx_size) + { + FIXME("Non-indexed instanced drawing is not supported\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(si->elements); ++i) + { + if (!(si->use_map & (1u << i))) + continue; + + if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA) + instanced_elements[instanced_element_count++] = i; + } + + for (i = 0; i < instance_count; ++i) + { + /* Specify the instanced attributes using immediate mode calls. */ + for (j = 0; j < instanced_element_count; ++j) + { + const struct wined3d_stream_info_element *element; + unsigned int element_idx; + const BYTE *ptr; + + element_idx = instanced_elements[j]; + element = &si->elements[element_idx]; + ptr = element->data.addr + element->stride * i; + if (element->data.buffer_object) + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, context); + ops->generic[element->format->emit_idx](element_idx, ptr); + } + + if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + { + GL_EXTCALL(glDrawElementsBaseVertex(state->gl_primitive_type, count, idx_type, + (const char *)idx_data + (idx_size * start_idx), base_vertex_idx)); checkGLcall("glDrawElementsBaseVertex"); } else { - gl_info->gl_ops.gl.p_glDrawElements(primitive_type, count, - idxtype, (const char *)idx_data + (idx_size * start_idx)); + gl_info->gl_ops.gl.p_glDrawElements(state->gl_primitive_type, count, idx_type, + (const char *)idx_data + (idx_size * start_idx)); checkGLcall("glDrawElements"); } } - else - { - if (instance_count) - { - if (start_instance) - FIXME("Start instance (%u) not supported.\n", start_instance); - GL_EXTCALL(glDrawArraysInstanced(primitive_type, start_idx, count, instance_count)); - checkGLcall("glDrawArraysInstanced"); - } - else - { - gl_info->gl_ops.gl.p_glDrawArrays(primitive_type, start_idx, count); - checkGLcall("glDrawArrays"); - } - } } -/* - * Actually draw using the supplied information. - * Slower GL version which extracts info about each vertex in turn - */ +static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size, + unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx) +{ + if (!idx_data) + return start_idx + vertex_idx; + if (idx_size == 2) + return ((const WORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx; + return ((const DWORD *)idx_data)[start_idx + vertex_idx] + base_vertex_idx; +} /* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -static void draw_strided_slow(const struct wined3d_state *state, struct wined3d_context *context, -#else /* STAGING_CSMT */ -static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, -#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, - const void *idxData, UINT idxSize, UINT startIdx) +static void draw_primitive_immediate_mode(struct wined3d_context *context, const struct wined3d_state *state, + const struct wined3d_stream_info *si, const void *idx_data, unsigned int idx_size, + int base_vertex_idx, unsigned int start_idx, unsigned int vertex_count, unsigned int instance_count) { - unsigned int textureNo; - const WORD *pIdxBufS = NULL; - const DWORD *pIdxBufL = NULL; - UINT vx_index; -#if !defined(STAGING_CSMT) - const struct wined3d_state *state = &device->state; -#endif /* STAGING_CSMT */ - LONG SkipnStrides = startIdx; - BOOL pixelShader = use_ps(state); - BOOL specular_fog = FALSE; - const BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; - const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL; - const struct wined3d_gl_info *gl_info = context->gl_info; + const BYTE *position = NULL, *normal = NULL, *diffuse = NULL, *specular = NULL; const struct wined3d_d3d_info *d3d_info = context->d3d_info; - const struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops; - UINT texture_stages = d3d_info->limits.ffp_blend_stages; + unsigned int coord_idx, stride_idx, texture_idx, vertex_idx; + const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_stream_info_element *element; - UINT num_untracked_materials; - DWORD tex_mask = 0; + const BYTE *tex_coords[WINED3DDP_MAXTEXCOORD]; + unsigned int texture_unit, texture_stages; + const struct wined3d_ffp_attrib_ops *ops; + unsigned int untracked_material_count; + unsigned int tex_mask = 0; + BOOL specular_fog = FALSE; + BOOL ps = use_ps(state); + const void *ptr; - TRACE_(d3d_perf)("Using slow vertex array code\n"); + static unsigned int once; - /* Variable Initialization */ - if (idxSize) + if (!once++) + FIXME_(d3d_perf)("Drawing using immediate mode.\n"); + else + WARN_(d3d_perf)("Drawing using immediate mode.\n"); + + if (!idx_size && idx_data) + ERR("Non-NULL idx_data with 0 idx_size, this should never happen.\n"); + + if (instance_count) + FIXME("Instancing not implemented.\n"); + + /* Immediate mode drawing can't make use of indices in a VBO - get the + * data from the index buffer. */ + if (idx_size) + idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context) + state->index_offset; + + ops = &d3d_info->ffp_attrib_ops; + + gl_info->gl_ops.gl.p_glBegin(state->gl_primitive_type); + + if (use_vs(state) || d3d_info->ffp_generic_attributes) { - /* Immediate mode drawing can't make use of indices in a vbo - get the - * data from the index buffer. If the index buffer has no vbo (not - * supported or other reason), or with user pointer drawing idxData - * will be non-NULL. */ - if (!idxData) - idxData = buffer_get_sysmem(state->index_buffer, context); + for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx) + { + unsigned int use_map = si->use_map; + unsigned int element_idx; - if (idxSize == 2) pIdxBufS = idxData; - else pIdxBufL = idxData; - } else if (idxData) { - ERR("non-NULL idxData with 0 idxSize, this should never happen\n"); + stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx); + for (element_idx = MAX_ATTRIBS - 1; use_map; use_map &= ~(1u << element_idx), --element_idx) + { + if (!(use_map & 1u << element_idx)) + continue; + + ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx; + ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr); + } + } + + gl_info->gl_ops.gl.p_glEnd(); return; } - /* Start drawing in GL */ - gl_info->gl_ops.gl.p_glBegin(glPrimType); - if (si->use_map & (1u << WINED3D_FFP_POSITION)) - { - element = &si->elements[WINED3D_FFP_POSITION]; - position = element->data.addr; - } + position = si->elements[WINED3D_FFP_POSITION].data.addr; if (si->use_map & (1u << WINED3D_FFP_NORMAL)) - { - element = &si->elements[WINED3D_FFP_NORMAL]; - normal = element->data.addr; - } + normal = si->elements[WINED3D_FFP_NORMAL].data.addr; else - { - gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0); - } + gl_info->gl_ops.gl.p_glNormal3f(0.0f, 0.0f, 0.0f); - num_untracked_materials = context->num_untracked_materials; + untracked_material_count = context->num_untracked_materials; if (si->use_map & (1u << WINED3D_FFP_DIFFUSE)) { element = &si->elements[WINED3D_FFP_DIFFUSE]; diffuse = element->data.addr; - if (num_untracked_materials && element->format->id != WINED3DFMT_B8G8R8A8_UNORM) - FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format->id)); + if (untracked_material_count && element->format->id != WINED3DFMT_B8G8R8A8_UNORM) + FIXME("Implement diffuse color tracking from %s.\n", debug_d3dformat(element->format->id)); } else { @@ -178,7 +248,7 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_ element = &si->elements[WINED3D_FFP_SPECULAR]; specular = element->data.addr; - /* special case where the fog density is stored in the specular alpha channel */ + /* Special case where the fog density is stored in the specular alpha channel. */ if (state->render_states[WINED3D_RS_FOGENABLE] && (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT) @@ -186,455 +256,230 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_ { if (gl_info->supported[EXT_FOG_COORD]) { - if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM) specular_fog = TRUE; - else FIXME("Implement fog coordinates from %s\n", debug_d3dformat(element->format->id)); + if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM) + specular_fog = TRUE; + else + FIXME("Implement fog coordinates from %s.\n", debug_d3dformat(element->format->id)); } else { - static BOOL warned; + static unsigned int once; - if (!warned) - { - /* TODO: Use the fog table code from old ddraw */ - FIXME("Implement fog for transformed vertices in software\n"); - warned = TRUE; - } + if (!once++) + FIXME("Implement fog for transformed vertices in software.\n"); } } } else if (gl_info->supported[EXT_SECONDARY_COLOR]) { - GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); + GL_EXTCALL(glSecondaryColor3fEXT)(0.0f, 0.0f, 0.0f); } - for (textureNo = 0; textureNo < texture_stages; ++textureNo) + texture_stages = d3d_info->limits.ffp_blend_stages; + for (texture_idx = 0; texture_idx < texture_stages; ++texture_idx) { - int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX]; - DWORD texture_idx = context->tex_unit_map[textureNo]; - - if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0) + if (!gl_info->supported[ARB_MULTITEXTURE] && texture_idx > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); + FIXME("Program using multiple concurrent textures which this OpenGL implementation doesn't support.\n"); continue; } - if (!pixelShader && !state->textures[textureNo]) continue; - - if (texture_idx == WINED3D_UNMAPPED_STAGE) continue; - - if (coordIdx > 7) - { - TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo); + if (!ps && !state->textures[texture_idx]) continue; - } - else if (coordIdx < 0) + + texture_unit = context->tex_unit_map[texture_idx]; + if (texture_unit == WINED3D_UNMAPPED_STAGE) + continue; + + coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX]; + if (coord_idx > 7) { - FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx); + TRACE("Skipping generated coordinates (%#x) for texture %u.\n", coord_idx, texture_idx); continue; } - if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx))) + if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))) { - element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; - texCoords[coordIdx] = element->data.addr; - tex_mask |= (1u << textureNo); + tex_coords[coord_idx] = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].data.addr; + tex_mask |= (1u << texture_idx); } else { - TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo); + TRACE("Setting default coordinates for texture %u.\n", texture_idx); if (gl_info->supported[ARB_MULTITEXTURE]) - GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1)); + GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_unit, 0.0f, 0.0f, 0.0f, 1.0f)); else - gl_info->gl_ops.gl.p_glTexCoord4f(0, 0, 0, 1); + gl_info->gl_ops.gl.p_glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f); } } - /* We shouldn't start this function if any VBO is involved. Should I put a safety check here? - * Guess it's not necessary(we crash then anyway) and would only eat CPU time - */ + /* Blending data and point sizes are not supported by this function. They + * are not supported by the fixed function pipeline at all. A FIXME for + * them is printed after decoding the vertex declaration. */ + for (vertex_idx = 0; vertex_idx < vertex_count; ++vertex_idx) + { + unsigned int tmp_tex_mask; - /* For each primitive */ - for (vx_index = 0; vx_index < NumVertexes; ++vx_index) { - UINT texture, tmp_tex_mask; - /* Blending data and Point sizes are not supported by this function. They are not supported by the fixed - * function pipeline at all. A Fixme for them is printed after decoding the vertex declaration - */ + stride_idx = get_stride_idx(idx_data, idx_size, base_vertex_idx, start_idx, vertex_idx); - /* For indexed data, we need to go a few more strides in */ - if (idxData) + if (normal) { - /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) - SkipnStrides = pIdxBufS[startIdx + vx_index] + state->base_vertex_index; - else - SkipnStrides = pIdxBufL[startIdx + vx_index] + state->base_vertex_index; + ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride; + ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr); } - tmp_tex_mask = tex_mask; - for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture) - { - int coord_idx; - const void *ptr; - DWORD texture_idx; - - if (!(tmp_tex_mask & 1)) continue; - - coord_idx = state->texture_states[texture][WINED3D_TSS_TEXCOORD_INDEX]; - ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride); - - texture_idx = context->tex_unit_map[texture]; - ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx]( - GL_TEXTURE0_ARB + texture_idx, ptr); - } - - /* Diffuse -------------------------------- */ if (diffuse) { - const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride; - ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptrToCoords); + ptr = diffuse + stride_idx * si->elements[WINED3D_FFP_DIFFUSE].stride; + ops->diffuse[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptr); - if (num_untracked_materials) + if (untracked_material_count) { - DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0]; - unsigned char i; - float color[4]; + struct wined3d_color color; + unsigned int i; - color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0f; - color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0f; - color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0f; - color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0f; - - for (i = 0; i < num_untracked_materials; ++i) + wined3d_color_from_d3dcolor(&color, *(const DWORD *)ptr); + for (i = 0; i < untracked_material_count; ++i) { - gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], color); + gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], &color.r); } } } - /* Specular ------------------------------- */ if (specular) { - const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride; - ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptrToCoords); + ptr = specular + stride_idx * si->elements[WINED3D_FFP_SPECULAR].stride; + ops->specular[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptr); if (specular_fog) - { - DWORD specularColor = *(const DWORD *)ptrToCoords; - GL_EXTCALL(glFogCoordfEXT((float) (specularColor >> 24))); - } + GL_EXTCALL(glFogCoordfEXT((float)(*(const DWORD *)ptr >> 24))); } - /* Normal -------------------------------- */ - if (normal) + tmp_tex_mask = tex_mask; + for (texture_idx = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture_idx) { - const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride; - ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords); + if (!(tmp_tex_mask & 1)) + continue; + + coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX]; + ptr = tex_coords[coord_idx] + (stride_idx * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride); + ops->texcoord[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx]( + GL_TEXTURE0_ARB + context->tex_unit_map[texture_idx], ptr); } - /* Position -------------------------------- */ if (position) { - const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride; - ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords); + ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride; + ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr); } - - /* For non indexed mode, step onto next parts */ - if (!idxData) ++SkipnStrides; } gl_info->gl_ops.gl.p_glEnd(); checkGLcall("glEnd and previous calls"); } -/* Context activation is done by the caller. */ -static inline void send_attribute(const struct wined3d_gl_info *gl_info, - enum wined3d_format_id format, const UINT index, const void *ptr) -{ - switch(format) - { - case WINED3DFMT_R32_FLOAT: - GL_EXTCALL(glVertexAttrib1fv(index, ptr)); - break; - case WINED3DFMT_R32G32_FLOAT: - GL_EXTCALL(glVertexAttrib2fv(index, ptr)); - break; - case WINED3DFMT_R32G32B32_FLOAT: - GL_EXTCALL(glVertexAttrib3fv(index, ptr)); - break; - case WINED3DFMT_R32G32B32A32_FLOAT: - GL_EXTCALL(glVertexAttrib4fv(index, ptr)); - break; - - case WINED3DFMT_R8G8B8A8_UINT: - GL_EXTCALL(glVertexAttrib4ubv(index, ptr)); - break; - case WINED3DFMT_B8G8R8A8_UNORM: - if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) - { - const DWORD *src = ptr; - DWORD c = *src & 0xff00ff00u; - c |= (*src & 0xff0000u) >> 16; - c |= (*src & 0xffu) << 16; - GL_EXTCALL(glVertexAttrib4Nubv(index, (GLubyte *)&c)); - break; - } - /* else fallthrough */ - case WINED3DFMT_R8G8B8A8_UNORM: - GL_EXTCALL(glVertexAttrib4Nubv(index, ptr)); - break; - - case WINED3DFMT_R16G16_SINT: - GL_EXTCALL(glVertexAttrib2sv(index, ptr)); - break; - case WINED3DFMT_R16G16B16A16_SINT: - GL_EXTCALL(glVertexAttrib4sv(index, ptr)); - break; - - case WINED3DFMT_R16G16_SNORM: - { - GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1}; - GL_EXTCALL(glVertexAttrib4Nsv(index, s)); - break; - } - case WINED3DFMT_R16G16_UNORM: - { - GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1}; - GL_EXTCALL(glVertexAttrib4Nusv(index, s)); - break; - } - case WINED3DFMT_R16G16B16A16_SNORM: - GL_EXTCALL(glVertexAttrib4Nsv(index, ptr)); - break; - case WINED3DFMT_R16G16B16A16_UNORM: - GL_EXTCALL(glVertexAttrib4Nusv(index, ptr)); - break; - - case WINED3DFMT_R10G10B10A2_UINT: - FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n"); - /*glVertexAttrib3usvARB(instancedData[j], (GLushort *) ptr); Does not exist */ - break; - case WINED3DFMT_R10G10B10A2_SNORM: - FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n"); - /*glVertexAttrib3NusvARB(instancedData[j], (GLushort *) ptr); Does not exist */ - break; - - case WINED3DFMT_R16G16_FLOAT: - /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4 - * byte float according to the IEEE standard - */ - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex */ - GL_EXTCALL(glVertexAttrib2hvNV(index, ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - float y = float_16_to_32(((const unsigned short *)ptr) + 1); - GL_EXTCALL(glVertexAttrib2f(index, x, y)); - } - break; - case WINED3DFMT_R16G16B16A16_FLOAT: - if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM]) - { - /* Not supported by GL_ARB_half_float_vertex */ - GL_EXTCALL(glVertexAttrib4hvNV(index, ptr)); - } - else - { - float x = float_16_to_32(((const unsigned short *)ptr) + 0); - float y = float_16_to_32(((const unsigned short *)ptr) + 1); - float z = float_16_to_32(((const unsigned short *)ptr) + 2); - float w = float_16_to_32(((const unsigned short *)ptr) + 3); - GL_EXTCALL(glVertexAttrib4f(index, x, y, z, w)); - } - break; - - default: - ERR("Unexpected attribute format: %s\n", debug_d3dformat(format)); - break; - } -} - -/* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -static void draw_strided_slow_vs(struct wined3d_context *context, const struct wined3d_state *state, -#else /* STAGING_CSMT */ -static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, -#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - LONG SkipnStrides = startIdx + state->load_base_vertex_index; - const DWORD *pIdxBufL = NULL; - const WORD *pIdxBufS = NULL; - UINT vx_index; - int i; - const BYTE *ptr; - - if (idxSize) - { - /* Immediate mode drawing can't make use of indices in a vbo - get the - * data from the index buffer. If the index buffer has no vbo (not - * supported or other reason), or with user pointer drawing idxData - * will be non-NULL. */ - if (!idxData) - idxData = buffer_get_sysmem(state->index_buffer, context); - - if (idxSize == 2) pIdxBufS = idxData; - else pIdxBufL = idxData; - } else if (idxData) { - ERR("non-NULL idxData with 0 idxSize, this should never happen\n"); - return; - } - - /* Start drawing in GL */ - gl_info->gl_ops.gl.p_glBegin(glPrimitiveType); - - for (vx_index = 0; vx_index < numberOfVertices; ++vx_index) - { - if (idxData) - { - /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) - SkipnStrides = pIdxBufS[startIdx + vx_index] + state->load_base_vertex_index; - else - SkipnStrides = pIdxBufL[startIdx + vx_index] + state->load_base_vertex_index; - } - - for (i = MAX_ATTRIBS - 1; i >= 0; i--) - { - if (!(si->use_map & (1u << i))) continue; - - ptr = si->elements[i].data.addr + si->elements[i].stride * SkipnStrides; - - send_attribute(gl_info, si->elements[i].format->id, i, ptr); - } - SkipnStrides++; - } - - gl_info->gl_ops.gl.p_glEnd(); -} - -/* Context activation is done by the caller. */ -#if defined(STAGING_CSMT) -static void draw_strided_instanced(struct wined3d_context *context, const struct wined3d_state *state, -#else /* STAGING_CSMT */ -static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, -#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - int numInstancedAttribs = 0, j; - UINT instancedData[sizeof(si->elements) / sizeof(*si->elements) /* 16 */]; - GLenum idxtype = idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; - UINT i; - - if (!idxSize) - { - /* This is a nasty thing. MSDN says no hardware supports that and apps have to use software vertex processing. - * We don't support this for now - * - * Shouldn't be too hard to support with opengl, in theory just call glDrawArrays instead of drawElements. - * But the StreamSourceFreq value has a different meaning in that situation. - */ - FIXME("Non-indexed instanced drawing is not supported\n"); - return; - } - - for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i) - { - if (!(si->use_map & (1u << i))) continue; - - if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA) - { - instancedData[numInstancedAttribs] = i; - numInstancedAttribs++; - } - } - - for (i = 0; i < instance_count; ++i) - { - /* Specify the instanced attributes using immediate mode calls */ - for(j = 0; j < numInstancedAttribs; j++) { - const BYTE *ptr = si->elements[instancedData[j]].data.addr - + si->elements[instancedData[j]].stride * i; - if (si->elements[instancedData[j]].data.buffer_object) - { - struct wined3d_buffer *vb = state->streams[si->elements[instancedData[j]].stream_idx].buffer; - ptr += (ULONG_PTR)buffer_get_sysmem(vb, context); - } - - send_attribute(gl_info, si->elements[instancedData[j]].format->id, instancedData[j], ptr); - } - - if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) - { - GL_EXTCALL(glDrawElementsBaseVertex(glPrimitiveType, numberOfVertices, idxtype, - (const char *)idxData+(idxSize * startIdx), base_vertex_index)); - checkGLcall("glDrawElementsBaseVertex"); - } - else - { - gl_info->gl_ops.gl.p_glDrawElements(glPrimitiveType, numberOfVertices, idxtype, - (const char *)idxData + (idxSize * startIdx)); - checkGLcall("glDrawElements"); - } - } -} - static void remove_vbos(struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_stream_info *s) { unsigned int i; - for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i) + for (i = 0; i < ARRAY_SIZE(s->elements); ++i) { struct wined3d_stream_info_element *e; - if (!(s->use_map & (1u << i))) continue; + if (!(s->use_map & (1u << i))) + continue; e = &s->elements[i]; if (e->data.buffer_object) { struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, context)); + e->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context); } } } +static BOOL use_transform_feedback(const struct wined3d_state *state) +{ + const struct wined3d_shader *shader; + if (!(shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY])) + return FALSE; + return shader->u.gs.so_desc.element_count; +} + +static void context_pause_transform_feedback(struct wined3d_context *context, BOOL force) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (!context->transform_feedback_active || context->transform_feedback_paused) + return; + + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK2]) + { + GL_EXTCALL(glPauseTransformFeedback()); + checkGLcall("glPauseTransformFeedback"); + context->transform_feedback_paused = 1; + return; + } + + WARN("Cannot pause transform feedback operations.\n"); + + if (force) + context_end_transform_feedback(context); +} + +static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) +{ + GLenum gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); + switch (gl_primitive_type) + { + case GL_POINTS: + return GL_POINTS; + + case GL_LINE_STRIP: + case GL_LINE_STRIP_ADJACENCY: + case GL_LINES_ADJACENCY: + case GL_LINES: + return GL_LINES; + + case GL_TRIANGLE_FAN: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_STRIP_ADJACENCY: + case GL_TRIANGLES_ADJACENCY: + case GL_TRIANGLES: + return GL_TRIANGLES; + + default: + return gl_primitive_type; + } +} + /* Routine common to the draw primitive and draw indexed primitive routines */ -#if defined(STAGING_CSMT) void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, - UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, - BOOL indexed) + int base_vertex_idx, unsigned int start_idx, unsigned int index_count, + unsigned int start_instance, unsigned int instance_count, BOOL indexed) { -#else /* STAGING_CSMT */ -void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, - UINT start_instance, UINT instance_count, BOOL indexed) -{ - const struct wined3d_state *state = &device->state; -#endif /* STAGING_CSMT */ + BOOL emulation = FALSE, rasterizer_discard = FALSE; + const struct wined3d_fb_state *fb = state->fb; const struct wined3d_stream_info *stream_info; struct wined3d_event_query *ib_query = NULL; + struct wined3d_rendertarget_view *dsv, *rtv; struct wined3d_stream_info si_emulated; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - BOOL emulation = FALSE; + unsigned int i, idx_size = 0; const void *idx_data = NULL; - UINT idx_size = 0; - unsigned int i; - if (!index_count) return; + if (!index_count) + return; -#if defined(STAGING_CSMT) - context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0])); -#else /* STAGING_CSMT */ - context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0])); -#endif /* STAGING_CSMT */ + if (!(rtv = fb->render_targets[0])) + rtv = fb->depth_stencil; + if (rtv) + context = context_acquire(device, wined3d_texture_from_resource(rtv->resource), rtv->sub_resource_idx); + else + context = context_acquire(device, NULL, 0); if (!context->valid) { context_release(context); @@ -643,91 +488,40 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co } gl_info = context->gl_info; - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + if (!use_transform_feedback(state)) + context_pause_transform_feedback(context, TRUE); + + for (i = 0; i < gl_info->limits.buffers; ++i) { -#if defined(STAGING_CSMT) - struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]); - if (target && target->resource.format->id != WINED3DFMT_NULL) + if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) + continue; + + if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) { - if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) - { - wined3d_resource_load_location(&target->resource, context, target->container->resource.draw_binding); - wined3d_resource_invalidate_location(&target->resource, ~target->container->resource.draw_binding); -#else /* STAGING_CSMT */ - struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); - if (target && target->resource.format->id != WINED3DFMT_NULL) - { - if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) - { - surface_load_location(target, context, target->container->resource.draw_binding); - surface_invalidate_location(target, ~target->container->resource.draw_binding); -#endif /* STAGING_CSMT */ - } - else - { - wined3d_surface_prepare(target, context, target->container->resource.draw_binding); - } - } - } - -#if defined(STAGING_CSMT) - if (state->fb.depth_stencil) - { - /* Note that this depends on the context_acquire() call above to set - * context->render_offscreen properly. We don't currently take the - * Z-compare function into account, but we could skip loading the - * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note - * that we never copy the stencil data.*/ - DWORD location = context->render_offscreen ? state->fb.depth_stencil->resource->draw_binding - : WINED3D_LOCATION_DRAWABLE; - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); - - if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) - { - RECT current_rect, draw_rect, r; - - if (!context->render_offscreen && ds != device->cs->onscreen_depth_stencil) - wined3d_cs_switch_onscreen_ds(device->cs, context, ds); - - if (ds->resource.locations & location) -#else /* STAGING_CSMT */ - if (device->fb.depth_stencil) - { - /* Note that this depends on the context_acquire() call above to set - * context->render_offscreen properly. We don't currently take the - * Z-compare function into account, but we could skip loading the - * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note - * that we never copy the stencil data.*/ - DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding - : WINED3D_LOCATION_DRAWABLE; - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); - - if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) - { - RECT current_rect, draw_rect, r; - - if (!context->render_offscreen && ds != device->onscreen_depth_stencil) - device_switch_onscreen_ds(device, context, ds); - - if (ds->locations & location) -#endif /* STAGING_CSMT */ - SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); - else - SetRectEmpty(¤t_rect); - - wined3d_get_draw_rect(state, &draw_rect); - - IntersectRect(&r, &draw_rect, ¤t_rect); - if (!EqualRect(&r, &draw_rect)) - surface_load_ds_location(ds, context, location); - else - wined3d_surface_prepare(ds, context, location); + wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); + wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); } else - wined3d_surface_prepare(ds, context, location); + { + wined3d_rendertarget_view_prepare_location(rtv, context, rtv->resource->draw_binding); + } + } + + if ((dsv = fb->depth_stencil)) + { + /* Note that this depends on the context_acquire() call above to set + * context->render_offscreen properly. We don't currently take the + * Z-compare function into account, but we could skip loading the + * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note + * that we never copy the stencil data.*/ + DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; + + if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + wined3d_rendertarget_view_load_location(dsv, context, location); + else + wined3d_rendertarget_view_prepare_location(dsv, context, location); } -#if defined(STAGING_CSMT) if (!context_apply_draw_state(context, device, state)) { context_release(context); @@ -735,33 +529,12 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co return; } - if (state->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) + if (dsv && state->render_states[WINED3D_RS_ZWRITEENABLE]) { - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); -#else /* STAGING_CSMT */ - if (!context_apply_draw_state(context, device)) - { - context_release(context); - WARN("Unable to apply draw state, skipping draw.\n"); - return; - } + DWORD location = context->render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; - if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) - { - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); -#endif /* STAGING_CSMT */ - DWORD location = context->render_offscreen ? ds->container->resource.draw_binding : WINED3D_LOCATION_DRAWABLE; - - surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); - } - - if ((!gl_info->supported[WINED3D_GL_VERSION_2_0] - || !gl_info->supported[NV_POINT_SPRITE]) - && context->render_offscreen - && state->render_states[WINED3D_RS_POINTSPRITEENABLE] - && state->gl_primitive_type == GL_POINTS) - { - FIXME("Point sprite coordinate origin switching not supported.\n"); + wined3d_rendertarget_view_validate_location(dsv, location); + wined3d_rendertarget_view_invalidate_location(dsv, ~location); } stream_info = &context->stream_info; @@ -772,12 +545,15 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co { struct wined3d_buffer *index_buffer = state->index_buffer; if (!index_buffer->buffer_object || !stream_info->all_vbo) + { idx_data = index_buffer->resource.heap_memory; + } else { ib_query = index_buffer->query; idx_data = NULL; } + idx_data = (const BYTE *)idx_data + state->index_offset; if (state->index_format == WINED3DFMT_R16_UINT) idx_size = 2; @@ -820,79 +596,111 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co } } + if (use_transform_feedback(state)) + { + const struct wined3d_shader *shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; + + if (shader->u.gs.so_desc.rasterizer_stream_idx == WINED3D_NO_RASTERIZER_STREAM) + { + glEnable(GL_RASTERIZER_DISCARD); + checkGLcall("enable rasterizer discard"); + rasterizer_discard = TRUE; + } + + if (context->transform_feedback_paused) + { + GL_EXTCALL(glResumeTransformFeedback()); + checkGLcall("glResumeTransformFeedback"); + context->transform_feedback_paused = 0; + } + else if (!context->transform_feedback_active) + { + GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type); + GL_EXTCALL(glBeginTransformFeedback(mode)); + checkGLcall("glBeginTransformFeedback"); + context->transform_feedback_active = 1; + } + } + + if (state->gl_primitive_type == GL_PATCHES) + { + GL_EXTCALL(glPatchParameteri(GL_PATCH_VERTICES, state->gl_patch_vertices)); + checkGLcall("glPatchParameteri"); + } + if (context->use_immediate_mode_draw || emulation) - { - /* Immediate mode drawing. */ - if (use_vs(state)) - { - static BOOL warned; - - if (!warned++) - FIXME("Using immediate mode with vertex shaders for half float emulation.\n"); - else - WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); - -#if defined(STAGING_CSMT) - draw_strided_slow_vs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } - else - { - if (context->d3d_info->ffp_generic_attributes) - draw_strided_slow_vs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - else - draw_strided_slow(state, context, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } - } - else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) - { - /* Instancing emulation by mixing immediate mode and arrays. */ - draw_strided_instanced(context, state, stream_info, index_count, state->gl_primitive_type, - idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); - } + draw_primitive_immediate_mode(context, state, stream_info, idx_data, + idx_size, base_vertex_idx, start_idx, index_count, instance_count); else + draw_primitive_arrays(context, state, idx_data, idx_size, base_vertex_idx, + start_idx, index_count, start_instance, instance_count); + + if (context->uses_uavs) { - draw_strided_fast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, -#else /* STAGING_CSMT */ - drawStridedSlowVs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } - else - { - if (context->d3d_info->ffp_generic_attributes) - drawStridedSlowVs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - else - drawStridedSlow(device, context, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } + GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); + checkGLcall("glMemoryBarrier"); } - else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) + + context_pause_transform_feedback(context, FALSE); + + if (rasterizer_discard) { - /* Instancing emulation by mixing immediate mode and arrays. */ - drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, - idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); - } - else - { - drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, -#endif /* STAGING_CSMT */ - start_idx, state->base_vertex_index, start_instance, instance_count); + glDisable(GL_RASTERIZER_DISCARD); + checkGLcall("disable rasterizer discard"); } if (ib_query) wined3d_event_query_issue(ib_query, device); for (i = 0; i < context->num_buffer_queries; ++i) - { wined3d_event_query_issue(context->buffer_queries[i], device); - } if (wined3d_settings.strict_draw_ordering) gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); - TRACE("Done all gl drawing\n"); + TRACE("Done all gl drawing.\n"); +} + +void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) +{ + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + context = context_acquire(device, NULL, 0); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping dispatch.\n"); + return; + } + gl_info = context->gl_info; + + if (!gl_info->supported[ARB_COMPUTE_SHADER]) + { + context_release(context); + FIXME("OpenGL implementation does not support compute shaders.\n"); + return; + } + + context_apply_compute_state(context, device, state); + + if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE]) + { + context_release(context); + WARN("No compute shader bound, skipping dispatch.\n"); + return; + } + + GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z)); + checkGLcall("glDispatchCompute"); + + GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); + checkGLcall("glMemoryBarrier"); + + if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); } diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index d5724a0eecb..5ce0863a1d1 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -36,10 +36,31 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(winediag); #define WINED3D_GLSL_SAMPLE_PROJECTED 0x01 -#define WINED3D_GLSL_SAMPLE_NPOT 0x02 -#define WINED3D_GLSL_SAMPLE_LOD 0x04 -#define WINED3D_GLSL_SAMPLE_GRAD 0x08 -#define WINED3D_GLSL_SAMPLE_LOAD 0x10 +#define WINED3D_GLSL_SAMPLE_LOD 0x02 +#define WINED3D_GLSL_SAMPLE_GRAD 0x04 +#define WINED3D_GLSL_SAMPLE_LOAD 0x08 +#define WINED3D_GLSL_SAMPLE_OFFSET 0x10 + +static const struct +{ + unsigned int coord_size; + unsigned int resinfo_size; + const char *type_part; +} +resource_type_info[] = +{ + {0, 0, ""}, /* WINED3D_SHADER_RESOURCE_NONE */ + {1, 1, "Buffer"}, /* WINED3D_SHADER_RESOURCE_BUFFER */ + {1, 1, "1D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ + {2, 2, "2D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ + {2, 2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ + {3, 3, "3D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ + {3, 2, "Cube"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ + {2, 2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ + {3, 3, "2DArray"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ + {3, 3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ + {4, 3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ +}; struct glsl_dst_param { @@ -56,9 +77,11 @@ struct glsl_src_param struct glsl_sample_function { struct wined3d_string_buffer *name; - DWORD coord_mask; + unsigned int coord_mask; + unsigned int deriv_mask; enum wined3d_data_type data_type; BOOL output_single_component; + unsigned int offset_size; }; enum heap_node_op @@ -83,15 +106,14 @@ struct constant_heap }; /* GLSL shader private data */ -struct shader_glsl_priv { +struct shader_glsl_priv +{ struct wined3d_string_buffer shader_buffer; struct wined3d_string_buffer_list string_buffers; struct wine_rb_tree program_lookup; struct constant_heap vconst_heap; struct constant_heap pconst_heap; unsigned char *stack; - GLuint depth_blt_program_full[WINED3D_GL_RES_TYPE_COUNT]; - GLuint depth_blt_program_masked[WINED3D_GL_RES_TYPE_COUNT]; UINT next_constant_version; const struct wined3d_vertex_pipe_ops *vertex_pipe; @@ -107,9 +129,9 @@ struct glsl_vs_program struct list shader_entry; GLuint id; GLenum vertex_color_clamp; - GLint *uniform_f_locations; - GLint uniform_i_locations[MAX_CONST_I]; - GLint uniform_b_locations[MAX_CONST_B]; + GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]; + GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; + GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; GLint pos_fixup_location; GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; @@ -143,21 +165,38 @@ struct glsl_vs_program GLint pointsize_c_att_location; GLint pointsize_l_att_location; GLint pointsize_q_att_location; + GLint clip_planes_location; +}; + +struct glsl_hs_program +{ + struct list shader_entry; + GLuint id; +}; + +struct glsl_ds_program +{ + struct list shader_entry; + GLuint id; + + GLint pos_fixup_location; }; struct glsl_gs_program { struct list shader_entry; GLuint id; + + GLint pos_fixup_location; }; struct glsl_ps_program { struct list shader_entry; GLuint id; - GLint *uniform_f_locations; - GLint uniform_i_locations[MAX_CONST_I]; - GLint uniform_b_locations[MAX_CONST_B]; + GLint uniform_f_locations[WINED3D_MAX_PS_CONSTS_F]; + GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]; + GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; GLint bumpenv_mat_location[MAX_TEXTURES]; GLint bumpenv_lum_scale_location[MAX_TEXTURES]; GLint bumpenv_lum_offset_location[MAX_TEXTURES]; @@ -168,19 +207,29 @@ struct glsl_ps_program GLint fog_density_location; GLint fog_end_location; GLint fog_scale_location; + GLint alpha_test_ref_location; GLint ycorrection_location; GLint np2_fixup_location; GLint color_key_location; const struct ps_np2fixup_info *np2_fixup_info; }; +struct glsl_cs_program +{ + struct list shader_entry; + GLuint id; +}; + /* Struct to maintain data about a linked GLSL program */ struct glsl_shader_prog_link { struct wine_rb_entry program_lookup_entry; struct glsl_vs_program vs; + struct glsl_hs_program hs; + struct glsl_ds_program ds; struct glsl_gs_program gs; struct glsl_ps_program ps; + struct glsl_cs_program cs; GLuint id; DWORD constant_update_mask; UINT constant_version; @@ -189,12 +238,16 @@ struct glsl_shader_prog_link struct glsl_program_key { GLuint vs_id; + GLuint hs_id; + GLuint ds_id; GLuint gs_id; GLuint ps_id; + GLuint cs_id; }; struct shader_glsl_ctx_priv { const struct vs_compile_args *cur_vs_args; + const struct ds_compile_args *cur_ds_args; const struct ps_compile_args *cur_ps_args; struct ps_np2fixup_info *cur_np2fixup_info; struct wined3d_string_buffer_list *string_buffers; @@ -203,6 +256,7 @@ struct shader_glsl_ctx_priv { struct glsl_context_data { struct glsl_shader_prog_link *glsl_program; + GLenum vertex_color_clamp; }; struct glsl_ps_compiled_shader @@ -218,7 +272,24 @@ struct glsl_vs_compiled_shader GLuint id; }; +struct glsl_hs_compiled_shader +{ + GLuint id; +}; + +struct glsl_ds_compiled_shader +{ + struct ds_compile_args args; + GLuint id; +}; + struct glsl_gs_compiled_shader +{ + struct gs_compile_args args; + GLuint id; +}; + +struct glsl_cs_compiled_shader { GLuint id; }; @@ -228,10 +299,13 @@ struct glsl_shader_private union { struct glsl_vs_compiled_shader *vs; + struct glsl_hs_compiled_shader *hs; + struct glsl_ds_compiled_shader *ds; struct glsl_gs_compiled_shader *gs; struct glsl_ps_compiled_shader *ps; + struct glsl_cs_compiled_shader *cs; } gl_shaders; - UINT num_gl_shaders, shader_array_size; + unsigned int num_gl_shaders, shader_array_size; }; struct glsl_ffp_vertex_shader @@ -254,14 +328,19 @@ struct glsl_ffp_destroy_ctx const struct wined3d_gl_info *gl_info; }; +static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx); + static const char *debug_gl_shader_type(GLenum type) { switch (type) { #define WINED3D_TO_STR(u) case u: return #u WINED3D_TO_STR(GL_VERTEX_SHADER); + WINED3D_TO_STR(GL_TESS_CONTROL_SHADER); + WINED3D_TO_STR(GL_TESS_EVALUATION_SHADER); WINED3D_TO_STR(GL_GEOMETRY_SHADER); WINED3D_TO_STR(GL_FRAGMENT_SHADER); + WINED3D_TO_STR(GL_COMPUTE_SHADER); #undef WINED3D_TO_STR default: return wine_dbg_sprintf("UNKNOWN(%#x)", type); @@ -275,27 +354,41 @@ static const char *shader_glsl_get_prefix(enum wined3d_shader_type type) case WINED3D_SHADER_TYPE_VERTEX: return "vs"; + case WINED3D_SHADER_TYPE_HULL: + return "hs"; + + case WINED3D_SHADER_TYPE_DOMAIN: + return "ds"; + case WINED3D_SHADER_TYPE_GEOMETRY: return "gs"; case WINED3D_SHADER_TYPE_PIXEL: return "ps"; + case WINED3D_SHADER_TYPE_COMPUTE: + return "cs"; + default: FIXME("Unhandled shader type %#x.\n", type); return "unknown"; } } -static const char *shader_glsl_get_version(const struct wined3d_gl_info *gl_info, - const struct wined3d_shader_version *version) +static unsigned int shader_glsl_get_version(const struct wined3d_gl_info *gl_info) { - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - return "#version 150"; - else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30) && version && version->major >= 4) - return "#version 130"; + if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)) + return 150; + else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)) + return 130; else - return "#version 120"; + return 120; +} + +static void shader_glsl_add_version_declaration(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info) +{ + shader_addline(buffer, "#version %u\n", shader_glsl_get_version(gl_info)); } static void shader_glsl_append_imm_vec4(struct wined3d_string_buffer *buffer, const float *values) @@ -309,6 +402,27 @@ static void shader_glsl_append_imm_vec4(struct wined3d_string_buffer *buffer, co shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]); } +static void shader_glsl_append_imm_ivec(struct wined3d_string_buffer *buffer, + const int *values, unsigned int size) +{ + int i; + + if (!size || size > 4) + { + ERR("Invalid vector size %u.\n", size); + return; + } + + if (size > 1) + shader_addline(buffer, "ivec%u(", size); + + for (i = 0; i < size; ++i) + shader_addline(buffer, i ? ", %#x" : "%#x", values[i]); + + if (size > 1) + shader_addline(buffer, ")"); +} + static const char *get_info_log_line(const char **ptr) { const char *p, *q; @@ -399,8 +513,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf char *source = NULL; GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count)); - shaders = HeapAlloc(GetProcessHeap(), 0, shader_count * sizeof(*shaders)); - if (!shaders) + if (!(shaders = wined3d_calloc(shader_count, sizeof(*shaders)))) { ERR("Failed to allocate shader array memory.\n"); return; @@ -463,56 +576,373 @@ void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint pro print_glsl_info_log(gl_info, program, TRUE); } -/* Context activation is done by the caller. */ -static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info, - struct shader_glsl_priv *priv, const DWORD *tex_unit_map, GLuint program_id) +static BOOL shader_glsl_use_layout_qualifier(const struct wined3d_gl_info *gl_info) { - unsigned int mapped_unit; - struct wined3d_string_buffer *sampler_name = string_buffer_get(&priv->string_buffers); - const char *prefix; - unsigned int i, j; - GLint name_loc; + /* Layout qualifiers were introduced in GLSL 1.40. The Nvidia Legacy GPU + * driver (series 340.xx) doesn't parse layout qualifiers in older GLSL + * versions. */ + return shader_glsl_get_version(gl_info) >= 140; +} - static const struct +static BOOL shader_glsl_use_layout_binding_qualifier(const struct wined3d_gl_info *gl_info) +{ + return gl_info->supported[ARB_SHADING_LANGUAGE_420PACK] && shader_glsl_use_layout_qualifier(gl_info); +} + +static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, + struct shader_glsl_priv *priv, GLuint program_id, + const struct wined3d_shader_reg_maps *reg_maps) +{ + const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); + struct wined3d_string_buffer *name; + unsigned int i, base, count; + GLuint block_idx; + + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + return; + + name = string_buffer_get(&priv->string_buffers); + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, reg_maps->shader_version.type, &base, &count); + for (i = 0; i < count; ++i) { - enum wined3d_shader_type type; - unsigned int base_idx; - unsigned int count; + if (!reg_maps->cb_sizes[i]) + continue; + + string_buffer_sprintf(name, "block_%s_cb%u", prefix, i); + block_idx = GL_EXTCALL(glGetUniformBlockIndex(program_id, name->buffer)); + GL_EXTCALL(glUniformBlockBinding(program_id, block_idx, base + i)); } - sampler_info[] = - { - {WINED3D_SHADER_TYPE_PIXEL, 0, MAX_FRAGMENT_SAMPLERS}, - {WINED3D_SHADER_TYPE_VERTEX, MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS}, - }; - - for (i = 0; i < ARRAY_SIZE(sampler_info); ++i) - { - prefix = shader_glsl_get_prefix(sampler_info[i].type); - - for (j = 0; j < sampler_info[i].count; ++j) - { - string_buffer_sprintf(sampler_name, "%s_sampler%u", prefix, j); - name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name->buffer)); - if (name_loc == -1) - continue; - - mapped_unit = tex_unit_map[sampler_info[i].base_idx + j]; - if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers) - { - ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name->buffer, mapped_unit); - continue; - } - - TRACE("Loading sampler %s on unit %u.\n", sampler_name->buffer, mapped_unit); - GL_EXTCALL(glUniform1i(name_loc, mapped_unit)); - } - } - checkGLcall("glUniform1i"); - string_buffer_release(&priv->string_buffers, sampler_name); + checkGLcall("glUniformBlockBinding"); + string_buffer_release(&priv->string_buffers, name); } /* Context activation is done by the caller. */ -static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants, +static void shader_glsl_load_samplers_range(const struct wined3d_gl_info *gl_info, + struct shader_glsl_priv *priv, GLuint program_id, const char *prefix, + unsigned int base, unsigned int count, const DWORD *tex_unit_map) +{ + struct wined3d_string_buffer *sampler_name = string_buffer_get(&priv->string_buffers); + unsigned int i, mapped_unit; + GLint name_loc; + + for (i = 0; i < count; ++i) + { + string_buffer_sprintf(sampler_name, "%s_sampler%u", prefix, i); + name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name->buffer)); + if (name_loc == -1) + continue; + + mapped_unit = tex_unit_map ? tex_unit_map[base + i] : base + i; + if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers) + { + ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name->buffer, mapped_unit); + continue; + } + + TRACE("Loading sampler %s on unit %u.\n", sampler_name->buffer, mapped_unit); + GL_EXTCALL(glUniform1i(name_loc, mapped_unit)); + } + checkGLcall("Load sampler bindings"); + string_buffer_release(&priv->string_buffers, sampler_name); +} + +static unsigned int shader_glsl_map_tex_unit(const struct wined3d_context *context, + const struct wined3d_shader_version *shader_version, unsigned int sampler_idx) +{ + const DWORD *tex_unit_map; + unsigned int base, count; + + tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count); + if (sampler_idx >= count) + return WINED3D_UNMAPPED_STAGE; + if (!tex_unit_map) + return base + sampler_idx; + return tex_unit_map[base + sampler_idx]; +} + +static void shader_glsl_append_sampler_binding_qualifier(struct wined3d_string_buffer *buffer, + const struct wined3d_context *context, const struct wined3d_shader_version *shader_version, + unsigned int sampler_idx) +{ + unsigned int mapped_unit = shader_glsl_map_tex_unit(context, shader_version, sampler_idx); + if (mapped_unit != WINED3D_UNMAPPED_STAGE) + shader_addline(buffer, "layout(binding = %u)\n", mapped_unit); + else + ERR("Unmapped sampler %u.\n", sampler_idx); +} + +/* Context activation is done by the caller. */ +static void shader_glsl_load_samplers(const struct wined3d_context *context, + struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_shader_version *shader_version; + const DWORD *tex_unit_map; + unsigned int base, count; + const char *prefix; + + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + return; + + shader_version = reg_maps ? ®_maps->shader_version : NULL; + prefix = shader_glsl_get_prefix(shader_version ? shader_version->type : WINED3D_SHADER_TYPE_PIXEL); + tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count); + shader_glsl_load_samplers_range(gl_info, priv, program_id, prefix, base, count, tex_unit_map); +} + +static void shader_glsl_load_icb(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, + GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps) +{ + const struct wined3d_shader_immediate_constant_buffer *icb = reg_maps->icb; + + if (icb) + { + struct wined3d_string_buffer *icb_name = string_buffer_get(&priv->string_buffers); + const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); + GLint icb_location; + + string_buffer_sprintf(icb_name, "%s_icb", prefix); + icb_location = GL_EXTCALL(glGetUniformLocation(program_id, icb_name->buffer)); + GL_EXTCALL(glUniform4fv(icb_location, icb->vec4_count, (const GLfloat *)icb->data)); + checkGLcall("Load immediate constant buffer"); + + string_buffer_release(&priv->string_buffers, icb_name); + } +} + +/* Context activation is done by the caller. */ +static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, + GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps) +{ + const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); + struct wined3d_string_buffer *name; + GLint location; + unsigned int i; + + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + return; + + name = string_buffer_get(&priv->string_buffers); + for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i) + { + if (!reg_maps->uav_resource_info[i].type) + continue; + + string_buffer_sprintf(name, "%s_image%u", prefix, i); + location = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + if (location == -1) + continue; + + TRACE("Loading image %s on unit %u.\n", name->buffer, i); + GL_EXTCALL(glUniform1i(location, i)); + } + checkGLcall("Load image bindings"); + string_buffer_release(&priv->string_buffers, name); +} + +/* Context activation is done by the caller. */ +static void shader_glsl_load_program_resources(const struct wined3d_context *context, + struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader) +{ + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + + shader_glsl_init_uniform_block_bindings(context->gl_info, priv, program_id, reg_maps); + shader_glsl_load_icb(context->gl_info, priv, program_id, reg_maps); + /* Texture unit mapping is set up to be the same each time the shader + * program is used so we can hardcode the sampler uniform values. */ + shader_glsl_load_samplers(context, priv, program_id, reg_maps); +} + +static void append_transform_feedback_varying(const char **varyings, unsigned int *varying_count, + char **strings, unsigned int *strings_length, struct wined3d_string_buffer *buffer) +{ + if (varyings && *strings) + { + char *ptr = *strings; + + varyings[*varying_count] = ptr; + + memcpy(ptr, buffer->buffer, buffer->content_size + 1); + ptr += buffer->content_size + 1; + + *strings = ptr; + } + + *strings_length += buffer->content_size + 1; + ++(*varying_count); +} + +static void append_transform_feedback_skip_components(const char **varyings, + unsigned int *varying_count, char **strings, unsigned int *strings_length, + struct wined3d_string_buffer *buffer, unsigned int component_count) +{ + unsigned int j; + + for (j = 0; j < component_count / 4; ++j) + { + string_buffer_sprintf(buffer, "gl_SkipComponents4"); + append_transform_feedback_varying(varyings, varying_count, strings, strings_length, buffer); + } + if (component_count % 4) + { + string_buffer_sprintf(buffer, "gl_SkipComponents%u", component_count % 4); + append_transform_feedback_varying(varyings, varying_count, strings, strings_length, buffer); + } +} + +static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc, + struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count, + char *strings, unsigned int *strings_length, GLenum buffer_mode) +{ + unsigned int i, buffer_idx, count, length, highest_output_slot, stride; + + count = length = 0; + highest_output_slot = 0; + for (buffer_idx = 0; buffer_idx < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++buffer_idx) + { + stride = 0; + + for (i = 0; i < so_desc->element_count; ++i) + { + const struct wined3d_stream_output_element *e = &so_desc->elements[i]; + + highest_output_slot = max(highest_output_slot, e->output_slot); + if (e->output_slot != buffer_idx) + continue; + + if (e->stream_idx) + { + FIXME("Unhandled stream %u.\n", e->stream_idx); + continue; + } + + stride += e->component_count; + + if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP) + { + append_transform_feedback_skip_components(varyings, &count, + &strings, &length, buffer, e->component_count); + continue; + } + + if (e->component_idx || e->component_count != 4) + { + FIXME("Unsupported component range %u-%u.\n", e->component_idx, e->component_count); + continue; + } + + string_buffer_sprintf(buffer, "shader_in_out.reg[%u]", e->register_idx); + append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); + } + + if (buffer_idx < so_desc->buffer_stride_count + && stride < so_desc->buffer_strides[buffer_idx] / 4) + { + unsigned int component_count = so_desc->buffer_strides[buffer_idx] / 4 - stride; + append_transform_feedback_skip_components(varyings, &count, + &strings, &length, buffer, component_count); + } + + if (highest_output_slot <= buffer_idx) + break; + + if (buffer_mode == GL_INTERLEAVED_ATTRIBS) + { + string_buffer_sprintf(buffer, "gl_NextBuffer"); + append_transform_feedback_varying(varyings, &count, &strings, &length, buffer); + } + } + + if (varying_count) + *varying_count = count; + if (strings_length) + *strings_length = length; +} + +static void shader_glsl_init_transform_feedback(const struct wined3d_context *context, + struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader) +{ + const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_string_buffer *buffer; + unsigned int i, count, length; + const char **varyings; + char *strings; + GLenum mode; + + if (!so_desc->element_count) + return; + + if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + mode = GL_INTERLEAVED_ATTRIBS; + } + else + { + unsigned int element_count[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0}; + + for (i = 0; i < so_desc->element_count; ++i) + { + if (so_desc->elements[i].register_idx == WINED3D_STREAM_OUTPUT_GAP) + { + FIXME("ARB_transform_feedback3 is needed for stream output gaps.\n"); + return; + } + ++element_count[so_desc->elements[i].output_slot]; + } + + if (element_count[0] == so_desc->element_count) + { + mode = GL_INTERLEAVED_ATTRIBS; + } + else + { + mode = GL_SEPARATE_ATTRIBS; + for (i = 0; i < ARRAY_SIZE(element_count); ++i) + { + if (element_count[i] != 1) + break; + } + for (; i < ARRAY_SIZE(element_count); ++i) + { + if (element_count[i]) + { + FIXME("Only single element per buffer is allowed in separate mode.\n"); + return; + } + } + } + } + + buffer = string_buffer_get(&priv->string_buffers); + + shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode); + + if (!(varyings = wined3d_calloc(count, sizeof(*varyings)))) + { + ERR("Out of memory.\n"); + string_buffer_release(&priv->string_buffers, buffer); + return; + } + if (!(strings = wined3d_calloc(length, sizeof(*strings)))) + { + ERR("Out of memory.\n"); + HeapFree(GetProcessHeap(), 0, varyings); + string_buffer_release(&priv->string_buffers, buffer); + return; + } + + shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, varyings, NULL, strings, NULL, mode); + GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode)); + checkGLcall("glTransformFeedbackVaryings"); + + HeapFree(GetProcessHeap(), 0, varyings); + HeapFree(GetProcessHeap(), 0, strings); + string_buffer_release(&priv->string_buffers, buffer); +} + +/* Context activation is done by the caller. */ +static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version) { unsigned int start = ~0U, end = 0; @@ -581,28 +1011,30 @@ static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, con } } if (start <= end) - GL_EXTCALL(glUniform4fv(constant_locations[start], end - start + 1, &constants[start * 4])); + GL_EXTCALL(glUniform4fv(constant_locations[start], end - start + 1, &constants[start].x)); checkGLcall("walk_constant_heap()"); } /* Context activation is done by the caller. */ -static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, GLint location, const GLfloat *data) +static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, + GLint location, const struct wined3d_vec4 *data) { GLfloat clamped_constant[4]; if (location == -1) return; - clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0f ? 1.0f : data[0]; - clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0f ? 1.0f : data[1]; - clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0f ? 1.0f : data[2]; - clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0f ? 1.0f : data[3]; + clamped_constant[0] = data->x < -1.0f ? -1.0f : data->x > 1.0f ? 1.0f : data->x; + clamped_constant[1] = data->y < -1.0f ? -1.0f : data->y > 1.0f ? 1.0f : data->y; + clamped_constant[2] = data->z < -1.0f ? -1.0f : data->z > 1.0f ? 1.0f : data->z; + clamped_constant[3] = data->w < -1.0f ? -1.0f : data->w > 1.0f ? 1.0f : data->w; GL_EXTCALL(glUniform4fv(location, 1, clamped_constant)); } /* Context activation is done by the caller. */ -static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const float *constants, - const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version) +static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, + const struct wined3d_vec4 *constants, const GLint *constant_locations, + const struct constant_heap *heap, unsigned char *stack, DWORD version) { int stack_idx = 0; unsigned int heap_idx = 1; @@ -611,7 +1043,7 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i if (heap->entries[heap_idx].version <= version) return; idx = heap->entries[heap_idx].idx; - apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]); + apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]); stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT; while (stack_idx >= 0) @@ -626,7 +1058,7 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i { heap_idx = left_idx; idx = heap->entries[heap_idx].idx; - apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]); + apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]); stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT; stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT; @@ -641,7 +1073,7 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i { heap_idx = right_idx; idx = heap->entries[heap_idx].idx; - apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]); + apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]); stack[stack_idx++] = HEAP_NODE_POP; stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT; @@ -659,9 +1091,9 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i } /* Context activation is done by the caller. */ -static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, - const float *constants, const GLint *constant_locations, const struct constant_heap *heap, - unsigned char *stack, UINT version) +static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, + const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, + unsigned char *stack, unsigned int version) { const struct wined3d_shader_lconst *lconst; @@ -674,7 +1106,7 @@ static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, con if (!shader->load_local_constsF) { - TRACE("No need to load local float constants for this shader\n"); + TRACE("No need to load local float constants for this shader.\n"); return; } @@ -687,8 +1119,8 @@ static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, con } /* Context activation is done by the caller. */ -static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, - const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set) +static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, + const struct wined3d_ivec4 *constants, const GLint locations[WINED3D_MAX_CONSTS_I], WORD constants_set) { unsigned int i; struct list* ptr; @@ -698,7 +1130,7 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con if (!(constants_set & 1)) continue; /* We found this uniform name in the program - go ahead and send the data */ - GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i * 4])); + GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i].x)); } /* Load immediate constants */ @@ -718,7 +1150,7 @@ static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, con /* Context activation is done by the caller. */ static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, - const GLint locations[MAX_CONST_B], const BOOL *constants, WORD constants_set) + const GLint locations[WINED3D_MAX_CONSTS_B], const BOOL *constants, WORD constants_set) { unsigned int i; struct list* ptr; @@ -753,7 +1185,11 @@ static void reset_program_constant_version(struct wine_rb_entry *entry, void *co static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) { - GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS]; + struct + { + float sx, sy; + } + np2fixup_constants[MAX_FRAGMENT_SAMPLERS]; UINT fixup = ps->np2_fixup_info->active; UINT i; @@ -761,7 +1197,6 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps { const struct wined3d_texture *tex = state->textures[i]; unsigned char idx = ps->np2_fixup_info->idx[i]; - GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4]; if (!tex) { @@ -769,19 +1204,11 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps continue; } - if (idx % 2) - { - tex_dim[2] = tex->pow2_matrix[0]; - tex_dim[3] = tex->pow2_matrix[5]; - } - else - { - tex_dim[0] = tex->pow2_matrix[0]; - tex_dim[1] = tex->pow2_matrix[5]; - } + np2fixup_constants[idx].sx = tex->pow2_matrix[0]; + np2fixup_constants[idx].sy = tex->pow2_matrix[5]; } - GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, np2fixup_constants)); + GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx)); } /* Taken and adapted from Mesa. */ @@ -1071,7 +1498,7 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con return; get_modelview_matrix(context, state, 0, &mv); - if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING) + if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) invert_matrix_3d(&mv, &mv); else invert_matrix(&mv, &mv); @@ -1128,10 +1555,10 @@ static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_con const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_color color; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col); - GL_EXTCALL(glUniform3fv(prog->vs.light_ambient_location, 1, col)); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_AMBIENT]); + GL_EXTCALL(glUniform3fv(prog->vs.light_ambient_location, 1, &color.r)); checkGLcall("glUniform3fv"); } @@ -1149,15 +1576,12 @@ static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined } static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *context, - const struct wined3d_state *state, unsigned int light, struct glsl_shader_prog_link *prog) + const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info, + struct glsl_shader_prog_link *prog) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_light_info *light_info = state->lights[light]; - struct wined3d_vec4 vec4; const struct wined3d_matrix *view = &state->transforms[WINED3D_TS_VIEW]; - - if (!light_info) - return; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_vec4 vec4; GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].diffuse, 1, &light_info->OriginalParms.diffuse.r)); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].specular, 1, &light_info->OriginalParms.specular.r)); @@ -1236,16 +1660,16 @@ static void shader_glsl_load_fog_uniform(const struct wined3d_context *context, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_color color; float start, end, scale; union { DWORD d; float f; } tmpvalue; - float col[4]; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col); - GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, col)); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_FOGCOLOR]); + GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &color.r)); tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY]; GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f)); get_fog_start_end(context, state, &start, &end); @@ -1255,6 +1679,21 @@ static void shader_glsl_load_fog_uniform(const struct wined3d_context *context, checkGLcall("fog emulation uniforms"); } +static void shader_glsl_clip_plane_uniform(const struct wined3d_context *context, + const struct wined3d_state *state, unsigned int index, struct glsl_shader_prog_link *prog) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_vec4 plane; + + /* Clip planes are affected by the view transform in d3d for FFP draws. */ + if (!use_vs(state)) + multiply_vector_matrix(&plane, &state->clip_planes[index], &state->transforms[WINED3D_TS_VIEW]); + else + plane = state->clip_planes[index]; + + GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x)); +} + /* Context activation is done by the caller (state handler). */ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) @@ -1290,24 +1729,35 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context update_mask = context->constant_update_mask & prog->constant_update_mask; if (update_mask & WINED3D_SHADER_CONST_VS_F) - shader_glsl_load_constantsF(vshader, gl_info, state->vs_consts_f, + shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f, prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version); if (update_mask & WINED3D_SHADER_CONST_VS_I) - shader_glsl_load_constantsI(vshader, gl_info, prog->vs.uniform_i_locations, state->vs_consts_i, - vshader->reg_maps.integer_constants); + shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i, + prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants); if (update_mask & WINED3D_SHADER_CONST_VS_B) shader_glsl_load_constantsB(vshader, gl_info, prog->vs.uniform_b_locations, state->vs_consts_b, vshader->reg_maps.boolean_constants); + if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES) + { + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + shader_glsl_clip_plane_uniform(context, state, i, prog); + } + if (update_mask & WINED3D_SHADER_CONST_VS_POINTSIZE) shader_glsl_pointsize_uniform(context, state, prog); - if (update_mask & WINED3D_SHADER_CONST_VS_POS_FIXUP) + if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP) { shader_get_position_fixup(context, state, position_fixup); - GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup)); + if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) + GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup)); + else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN]) + GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup)); + else + GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup)); checkGLcall("glUniform4fv"); } @@ -1357,18 +1807,79 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_FFP_LIGHTS) { + unsigned int point_idx, spot_idx, directional_idx, parallel_point_idx; + DWORD point_count = 0; + DWORD spot_count = 0; + DWORD directional_count = 0; + DWORD parallel_point_count = 0; + + for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + { + if (!state->lights[i]) + continue; + + switch (state->lights[i]->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + ++point_count; + break; + case WINED3D_LIGHT_SPOT: + ++spot_count; + break; + case WINED3D_LIGHT_DIRECTIONAL: + ++directional_count; + break; + case WINED3D_LIGHT_PARALLELPOINT: + ++parallel_point_count; + break; + default: + FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); + break; + } + } + point_idx = 0; + spot_idx = point_idx + point_count; + directional_idx = spot_idx + spot_count; + parallel_point_idx = directional_idx + directional_count; + shader_glsl_ffp_vertex_lightambient_uniform(context, state, prog); for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) - shader_glsl_ffp_vertex_light_uniform(context, state, i, prog); + { + const struct wined3d_light_info *light_info = state->lights[i]; + unsigned int idx; + + if (!light_info) + continue; + + switch (light_info->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + idx = point_idx++; + break; + case WINED3D_LIGHT_SPOT: + idx = spot_idx++; + break; + case WINED3D_LIGHT_DIRECTIONAL: + idx = directional_idx++; + break; + case WINED3D_LIGHT_PARALLELPOINT: + idx = parallel_point_idx++; + break; + default: + FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); + continue; + } + shader_glsl_ffp_vertex_light_uniform(context, state, idx, light_info, prog); + } } if (update_mask & WINED3D_SHADER_CONST_PS_F) - shader_glsl_load_constantsF(pshader, gl_info, state->ps_consts_f, + shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f, prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); if (update_mask & WINED3D_SHADER_CONST_PS_I) - shader_glsl_load_constantsI(pshader, gl_info, prog->ps.uniform_i_locations, state->ps_consts_i, - pshader->reg_maps.integer_constants); + shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i, + prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants); if (update_mask & WINED3D_SHADER_CONST_PS_B) shader_glsl_load_constantsB(pshader, gl_info, prog->ps.uniform_b_locations, state->ps_consts_b, @@ -1398,16 +1909,16 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_PS_Y_CORR) { - float correction_params[] = + const struct wined3d_vec4 correction_params = { - /* position is window relative, not viewport relative */ - context->render_offscreen ? 0.0f : (float)context->current_rt->resource.height, + /* Position is relative to the framebuffer, not the viewport. */ + context->render_offscreen ? 0.0f : (float)state->fb->render_targets[0]->height, context->render_offscreen ? 1.0f : -1.0f, 0.0f, 0.0f, }; - GL_EXTCALL(glUniform4fv(prog->ps.ycorrection_location, 1, correction_params)); + GL_EXTCALL(glUniform4fv(prog->ps.ycorrection_location, 1, &correction_params.x)); } if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) @@ -1417,12 +1928,12 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_FFP_PS) { - float col[4]; + struct wined3d_color color; if (prog->ps.tex_factor_location != -1) { - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); - GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, col)); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); + GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, &color.r)); } if (state->render_states[WINED3D_RS_SPECULARENABLE]) @@ -1435,8 +1946,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (prog->ps.tss_constant_location[i] == -1) continue; - D3DCOLORTOGLFLOAT4(state->texture_states[i][WINED3D_TSS_CONSTANT], col); - GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, col)); + wined3d_color_from_d3dcolor(&color, state->texture_states[i][WINED3D_TSS_CONSTANT]); + GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &color.r)); } checkGLcall("fixed function uniforms"); @@ -1445,6 +1956,14 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_PS_FOG) shader_glsl_load_fog_uniform(context, state, prog); + if (update_mask & WINED3D_SHADER_CONST_PS_ALPHA_TEST) + { + float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f; + + GL_EXTCALL(glUniform1f(prog->ps.alpha_test_ref_location, ref)); + checkGLcall("alpha test emulation uniform"); + } + if (priv->next_constant_version == UINT_MAX) { TRACE("Max constant version reached, resetting to 0.\n"); @@ -1499,11 +2018,6 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev { update_heap_entry(heap, i, priv->next_constant_version); } - - for (i = 0; i < device->context_count; ++i) - { - device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F; - } } static void shader_glsl_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) @@ -1516,11 +2030,6 @@ static void shader_glsl_update_float_pixel_constants(struct wined3d_device *devi { update_heap_entry(heap, i, priv->next_constant_version); } - - for (i = 0; i < device->context_count; ++i) - { - device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F; - } } static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info) @@ -1536,7 +2045,23 @@ static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_in static BOOL needs_legacy_glsl_syntax(const struct wined3d_gl_info *gl_info) { - return gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + return gl_info->glsl_version < MAKEDWORD_VERSION(1, 30); +} + +static BOOL shader_glsl_use_explicit_attrib_location(const struct wined3d_gl_info *gl_info) +{ + return gl_info->supported[ARB_EXPLICIT_ATTRIB_LOCATION] + && shader_glsl_use_layout_qualifier(gl_info) && !needs_legacy_glsl_syntax(gl_info); +} + +static BOOL shader_glsl_use_interface_blocks(const struct wined3d_gl_info *gl_info) +{ + return shader_glsl_get_version(gl_info) >= 150; +} + +static const char *get_attribute_keyword(const struct wined3d_gl_info *gl_info) +{ + return needs_legacy_glsl_syntax(gl_info) ? "attribute" : "in"; } static void PRINTF_ATTR(4, 5) declare_in_varying(const struct wined3d_gl_info *gl_info, @@ -1579,15 +2104,79 @@ static void PRINTF_ATTR(4, 5) declare_out_varying(const struct wined3d_gl_info * } } +static const char *shader_glsl_shader_input_name(const struct wined3d_gl_info *gl_info) +{ + return shader_glsl_use_interface_blocks(gl_info) ? "shader_in.reg" : "ps_link"; +} + +static const char *shader_glsl_shader_output_name(const struct wined3d_gl_info *gl_info) +{ + return shader_glsl_use_interface_blocks(gl_info) ? "shader_out.reg" : "ps_link"; +} + +static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info, + struct wined3d_string_buffer *buffer, unsigned int element_count) +{ + if (shader_glsl_use_interface_blocks(gl_info)) + shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in;\n", element_count); + else + declare_in_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count); +} + +static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info, + struct wined3d_string_buffer *buffer, unsigned int element_count) +{ + if (shader_glsl_use_interface_blocks(gl_info)) + shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; } shader_out;\n", element_count); + else + declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count); +} + +static const char *get_fragment_output(const struct wined3d_gl_info *gl_info) +{ + return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out"; +} + +static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) +{ + switch (primitive_type) + { + case WINED3D_PT_POINTLIST: + return "points"; + + case WINED3D_PT_LINELIST: + return "lines"; + + case WINED3D_PT_LINESTRIP: + return "line_strip"; + + case WINED3D_PT_TRIANGLELIST: + return "triangles"; + + case WINED3D_PT_TRIANGLESTRIP: + return "triangle_strip"; + + case WINED3D_PT_LINELIST_ADJ: + return "lines_adjacency"; + + case WINED3D_PT_TRIANGLELIST_ADJ: + return "triangles_adjacency"; + + default: + FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type)); + return ""; + } +} + static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned int idx) { const struct wined3d_shader_signature *input_signature = &shader->input_signature; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const BOOL *input_reg_used = shader->u.ps.input_reg_used; + DWORD input_reg_used = shader->u.ps.input_reg_used; unsigned int i; if (reg_maps->shader_version.major < 3) - return input_reg_used[idx]; + return input_reg_used & (1u << idx); for (i = 0; i < input_signature->element_count; ++i) { @@ -1598,36 +2187,88 @@ static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned if (shader_match_semantic(input->semantic_name, WINED3D_DECL_USAGE_COLOR) && input->semantic_idx == idx) - { - if (input_reg_used[input->register_idx]) - return TRUE; - else - return FALSE; - } + return input_reg_used & (1u << input->register_idx); } return FALSE; } +static BOOL glsl_is_shadow_sampler(const struct wined3d_shader *shader, + const struct ps_compile_args *ps_args, unsigned int resource_idx, unsigned int sampler_idx) +{ + const struct wined3d_shader_version *version = &shader->reg_maps.shader_version; + + if (version->major >= 4) + return shader->reg_maps.sampler_comparison_mode & (1u << sampler_idx); + else + return version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << resource_idx)); +} + +static void shader_glsl_declare_typed_vertex_attribute(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const char *vector_type, const char *scalar_type, + unsigned int index) +{ + shader_addline(buffer, "%s %s4 vs_in_%s%u;\n", + get_attribute_keyword(gl_info), vector_type, scalar_type, index); + shader_addline(buffer, "vec4 vs_in%u = %sBitsToFloat(vs_in_%s%u);\n", + index, scalar_type, scalar_type, index); +} + +static void shader_glsl_declare_generic_vertex_attribute(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, const struct wined3d_shader_signature_element *e) +{ + unsigned int index = e->register_idx; + + if (e->sysval_semantic == WINED3D_SV_VERTEX_ID) + { + shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID), 0.0, 0.0, 0.0);\n", + index); + return; + } + if (e->sysval_semantic == WINED3D_SV_INSTANCE_ID) + { + shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_InstanceID), 0.0, 0.0, 0.0);\n", + index); + return; + } + if (e->sysval_semantic && e->sysval_semantic != WINED3D_SV_POSITION) + FIXME("Unhandled sysval semantic %#x.\n", e->sysval_semantic); + + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = %u) ", index); + + switch (e->component_type) + { + case WINED3D_TYPE_UINT: + shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, "uvec", "uint", index); + break; + case WINED3D_TYPE_INT: + shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, "ivec", "int", index); + break; + + default: + FIXME("Unhandled type %#x.\n", e->component_type); + /* Fall through. */ + case WINED3D_TYPE_UNKNOWN: + case WINED3D_TYPE_FLOAT: + shader_addline(buffer, "%s vec4 vs_in%u;\n", get_attribute_keyword(gl_info), index); + break; + } +} + /** Generate the variable & register declarations for the GLSL output target */ static void shader_generate_glsl_declarations(const struct wined3d_context *context, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) { const struct wined3d_shader_version *version = ®_maps->shader_version; -#if defined(STAGING_CSMT) const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; const struct wined3d_gl_info *gl_info = context->gl_info; -#else /* STAGING_CSMT */ - const struct wined3d_state *state = &shader->device->state; - const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; - const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_fb_state *fb = &shader->device->fb; -#endif /* STAGING_CSMT */ - unsigned int i, extra_constants_needed = 0; + const struct wined3d_shader_indexable_temp *idx_temp_reg; + unsigned int uniform_block_base, uniform_block_count; const struct wined3d_shader_lconst *lconst; const char *prefix; + unsigned int i; DWORD map; prefix = shader_glsl_get_prefix(version->type); @@ -1681,7 +2322,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont * clipplane as well. */ max_constantsF = gl_info->limits.glsl_vs_float_constants - 3; if (vs_args->clip_enabled) - max_constantsF -= gl_info->limits.clipplanes; + max_constantsF -= gl_info->limits.user_clip_distances; max_constantsF -= wined3d_popcount(reg_maps->integer_constants); /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly, * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but @@ -1720,11 +2361,23 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants) shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool); - for (i = 0; i < WINED3D_MAX_CBS; ++i) + /* Declare immediate constant buffer */ + if (reg_maps->icb) + shader_addline(buffer, "uniform vec4 %s_icb[%u];\n", prefix, reg_maps->icb->vec4_count); + + /* Declare constant buffers */ + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, version->type, + &uniform_block_base, &uniform_block_count); + for (i = 0; i < min(uniform_block_count, WINED3D_MAX_CBS); ++i) { if (reg_maps->cb_sizes[i]) - shader_addline(buffer, "layout(std140) uniform block_%s_cb%u { vec4 %s_cb%u[%u]; };\n", + { + shader_addline(buffer, "layout(std140"); + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + shader_addline(buffer, ", binding = %u", uniform_block_base + i); + shader_addline(buffer, ") uniform block_%s_cb%u { vec4 %s_cb%u[%u]; };\n", prefix, i, prefix, i, reg_maps->cb_sizes[i]); + } } /* Declare texture samplers */ @@ -1764,9 +2417,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont break; } - shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << entry->sampler_idx)); + shadow_sampler = glsl_is_shadow_sampler(shader, ps_args, entry->resource_idx, entry->sampler_idx); switch (reg_maps->resource_info[entry->resource_idx].type) { + case WINED3D_SHADER_RESOURCE_BUFFER: + sampler_type = "samplerBuffer"; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_1D: if (shadow_sampler) sampler_type = "sampler1DShadow"; @@ -1802,51 +2459,114 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: if (shadow_sampler) - FIXME("Unsupported Cube shadow sampler.\n"); - sampler_type = "samplerCube"; + sampler_type = "samplerCubeShadow"; + else + sampler_type = "samplerCube"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY: + if (shadow_sampler) + sampler_type = "sampler1DArrayShadow"; + else + sampler_type = "sampler1DArray"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + if (shadow_sampler) + sampler_type = "sampler2DArrayShadow"; + else + sampler_type = "sampler2DArray"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY: + if (shadow_sampler) + sampler_type = "samplerCubeArrayShadow"; + else + sampler_type = "samplerCubeArray"; break; default: sampler_type = "unsupported_sampler"; - FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type); + FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type); break; } + + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + shader_glsl_append_sampler_binding_qualifier(buffer, context, version, entry->bind_idx); shader_addline(buffer, "uniform %s%s %s_sampler%u;\n", sampler_type_prefix, sampler_type, prefix, entry->bind_idx); } - /* Declare uniforms for NP2 texcoord fixup: - * This is NOT done inside the loop that declares the texture samplers - * since the NP2 fixup code is currently only used for the GeforceFX - * series and when forcing the ARB_npot extension off. Modern cards just - * skip the code anyway, so put it inside a separate loop. */ - if (version->type == WINED3D_SHADER_TYPE_PIXEL && ps_args->np2_fixup) + /* Declare images */ + for (i = 0; i < ARRAY_SIZE(reg_maps->uav_resource_info); ++i) { - struct ps_np2fixup_info *fixup = ctx_priv->cur_np2fixup_info; - UINT cur = 0; + const char *image_type_prefix, *image_type, *read_format; - /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height] - * while D3D has them in the (normalized) [0,1]x[0,1] range. - * samplerNP2Fixup stores texture dimensions and is updated through - * shader_glsl_load_np2fixup_constants when the sampler changes. */ + if (!reg_maps->uav_resource_info[i].type) + continue; - for (i = 0; i < shader->limits->sampler; ++i) + switch (reg_maps->uav_resource_info[i].data_type) { - if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1u << i))) - continue; + case WINED3D_DATA_FLOAT: + case WINED3D_DATA_UNORM: + case WINED3D_DATA_SNORM: + image_type_prefix = ""; + read_format = "r32f"; + break; - if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) - { - FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); - continue; - } + case WINED3D_DATA_INT: + image_type_prefix = "i"; + read_format = "r32i"; + break; - fixup->idx[i] = cur++; + case WINED3D_DATA_UINT: + image_type_prefix = "u"; + read_format = "r32ui"; + break; + + default: + image_type_prefix = ""; + read_format = ""; + ERR("Unhandled resource data type %#x.\n", reg_maps->uav_resource_info[i].data_type); + break; } - fixup->num_consts = (cur + 1) >> 1; - fixup->active = ps_args->np2_fixup; - shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts); + switch (reg_maps->uav_resource_info[i].type) + { + case WINED3D_SHADER_RESOURCE_BUFFER: + image_type = "imageBuffer"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_2D: + image_type = "image2D"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_3D: + image_type = "image3D"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + image_type = "image2DArray"; + break; + + default: + image_type = "unsupported_image"; + FIXME("Unhandled resource type %#x.\n", reg_maps->uav_resource_info[i].type); + break; + } + + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + shader_addline(buffer, "layout(binding = %u)\n", i); + if (reg_maps->uav_read_mask & (1u << i)) + shader_addline(buffer, "layout(%s) uniform %s%s %s_image%u;\n", + read_format, image_type_prefix, image_type, prefix, i); + else + shader_addline(buffer, "writeonly uniform %s%s %s_image%u;\n", + image_type_prefix, image_type, prefix, i); + + if (reg_maps->uav_counter_mask & (1u << i)) + shader_addline(buffer, "layout(binding = %u) uniform atomic_uint %s_counter%u;\n", + i, prefix, i); } /* Declare address variables */ @@ -1855,162 +2575,31 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i); } - if (version->type == WINED3D_SHADER_TYPE_VERTEX) - { - for (i = 0; i < shader->input_signature.element_count; ++i) - { - const struct wined3d_shader_signature_element *e = &shader->input_signature.elements[i]; - if (e->sysval_semantic == WINED3D_SV_INSTANCEID) - shader_addline(buffer, "vec4 %s_in%u = vec4(intBitsToFloat(gl_InstanceID), 0.0, 0.0, 0.0);\n", - prefix, e->register_idx); - else - shader_addline(buffer, "attribute vec4 %s_in%u;\n", prefix, e->register_idx); - } - - if (vs_args->point_size && !vs_args->per_vertex_point_size) - { - shader_addline(buffer, "uniform struct\n{\n"); - shader_addline(buffer, " float size;\n"); - shader_addline(buffer, " float size_min;\n"); - shader_addline(buffer, " float size_max;\n"); - shader_addline(buffer, "} ffp_point;\n"); - } - - if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] && version->major < 3) - { - declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_diffuse;\n"); - declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_specular;\n"); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); - declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); - } - - shader_addline(buffer, "uniform vec4 posFixup;\n"); - shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits->packed_output); - } - else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) - { - shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits->packed_input); - } - else if (version->type == WINED3D_SHADER_TYPE_PIXEL) - { - if (version->major < 3 || ps_args->vp_mode != vertexshader) - { - shader_addline(buffer, "uniform struct\n{\n"); - shader_addline(buffer, " vec4 color;\n"); - shader_addline(buffer, " float density;\n"); - shader_addline(buffer, " float end;\n"); - shader_addline(buffer, " float scale;\n"); - shader_addline(buffer, "} ffp_fog;\n"); - - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - { - if (glsl_is_color_reg_read(shader, 0)) - shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); - if (glsl_is_color_reg_read(shader, 1)) - shader_addline(buffer, "vec4 ffp_varying_specular;\n"); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); - shader_addline(buffer, "float ffp_varying_fogcoord;\n"); - } - else - { - if (glsl_is_color_reg_read(shader, 0)) - declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_diffuse;\n"); - if (glsl_is_color_reg_read(shader, 1)) - declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_specular;\n"); - declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); - shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); - declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); - } - } - - if (version->major >= 3) - { - UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); - -#if defined(STAGING_CSMT) - if (ps_args->vp_mode == vertexshader) -#else /* STAGING_CSMT */ - if (use_vs(state)) -#endif /* STAGING_CSMT */ - declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count); - shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); - } - - for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i) - { - if (!(map & 1)) - continue; - - shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", i); - - if (reg_maps->luminanceparams & (1u << i)) - { - shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", i); - shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", i); - extra_constants_needed++; - } - - extra_constants_needed++; - } - - if (ps_args->srgb_correction) - { - shader_addline(buffer, "const vec4 srgb_const0 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); - shader_addline(buffer, ";\n"); - shader_addline(buffer, "const vec4 srgb_const1 = "); - shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); - shader_addline(buffer, ";\n"); - } - if (reg_maps->vpos || reg_maps->usesdsy) - { - if (shader->limits->constant_float + extra_constants_needed - + 1 < gl_info->limits.glsl_ps_float_constants) - { - shader_addline(buffer, "uniform vec4 ycorrection;\n"); - extra_constants_needed++; - } - else - { -#if defined(STAGING_CSMT) - /* This happens because we do not have proper tracking of the - * constant registers that are actually used, only the max - * limit of the shader version. - * - * FIXME 2: This is wrong, there's no need to do this. Get rid of - * it and just create the uniform. - */ - FIXME("Cannot find a free uniform for vpos correction params\n"); -#else /* STAGING_CSMT */ - float ycorrection[] = - { - context->render_offscreen ? 0.0f : fb->render_targets[0]->height, - context->render_offscreen ? 1.0f : -1.0f, - 0.0f, - 0.0f, - }; - - /* This happens because we do not have proper tracking of the - * constant registers that are actually used, only the max - * limit of the shader version. */ - FIXME("Cannot find a free uniform for vpos correction params\n"); - shader_addline(buffer, "const vec4 ycorrection = "); - shader_glsl_append_imm_vec4(buffer, ycorrection); - shader_addline(buffer, ";\n"); -#endif /* STAGING_CSMT */ - } - shader_addline(buffer, "vec4 vpos;\n"); - } - } - /* Declare output register temporaries */ if (shader->limits->packed_output) shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits->packed_output); /* Declare temporary variables */ - for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i) + if (reg_maps->temporary_count) { - if (map & 1) shader_addline(buffer, "vec4 R%u;\n", i); + for (i = 0; i < reg_maps->temporary_count; ++i) + shader_addline(buffer, "vec4 R%u;\n", i); + } + else if (version->major < 4) + { + for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i) + { + if (map & 1) + shader_addline(buffer, "vec4 R%u;\n", i); + } + } + + /* Declare indexable temporary variables */ + LIST_FOR_EACH_ENTRY(idx_temp_reg, ®_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry) + { + if (idx_temp_reg->component_count != 4) + FIXME("Ignoring component count %u.\n", idx_temp_reg->component_count); + shader_addline(buffer, "vec4 X%u[%u];\n", idx_temp_reg->register_idx, idx_temp_reg->register_size); } /* Declare loop registers aLx */ @@ -2036,35 +2625,6 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont shader_addline(buffer, ";\n"); } } - - /* Start the main program. */ - shader_addline(buffer, "void main()\n{\n"); - - /* Direct3D applications expect integer vPos values, while OpenGL drivers - * add approximately 0.5. This causes off-by-one problems as spotted by - * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly - * 0.5, but rather something like 0.49999999 or 0.50000001, which still - * causes precision troubles when we just subtract 0.5. - * - * To deal with that, just floor() the position. This will eliminate the - * fraction on all cards. - * - * TODO: Test how this behaves with multisampling. - * - * An advantage of floor is that it works even if the driver doesn't add - * 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values - * to return in gl_FragCoord, even though coordinates specify the pixel - * centers instead of the pixel corners. This code will behave correctly - * on drivers that returns integer values. */ - if (version->type == WINED3D_SHADER_TYPE_PIXEL && reg_maps->vpos) - { - if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) - shader_addline(buffer, - "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n"); - else - shader_addline(buffer, - "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n"); - } } /***************************************************************************** @@ -2176,6 +2736,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_INPUT: + case WINED3DSPR_INCONTROLPOINT: if (version->type == WINED3D_SHADER_TYPE_VERTEX) { struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; @@ -2188,22 +2749,27 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; } - if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) + if (version->type == WINED3D_SHADER_TYPE_HULL + || version->type == WINED3D_SHADER_TYPE_DOMAIN + || version->type == WINED3D_SHADER_TYPE_GEOMETRY) { if (reg->idx[0].rel_addr) { if (reg->idx[1].rel_addr) - sprintf(register_name, "gs_in[%s + %u][%s + %u]", - rel_param0.param_str, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); + sprintf(register_name, "shader_in[%s + %u].reg[%s + %u]", + rel_param0.param_str, reg->idx[0].offset, + rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "gs_in[%s + %u][%u]", - rel_param0.param_str, reg->idx[0].offset, reg->idx[1].offset); + sprintf(register_name, "shader_in[%s + %u].reg[%u]", + rel_param0.param_str, reg->idx[0].offset, + reg->idx[1].offset); } else if (reg->idx[1].rel_addr) - sprintf(register_name, "gs_in[%u][%s + %u]", - reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); + sprintf(register_name, "shader_in[%u].reg[%s + %u]", reg->idx[0].offset, + rel_param1.param_str, reg->idx[1].offset); else - sprintf(register_name, "gs_in[%u][%u]", reg->idx[0].offset, reg->idx[1].offset); + sprintf(register_name, "shader_in[%u].reg[%u]", + reg->idx[0].offset, reg->idx[1].offset); break; } @@ -2219,7 +2785,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * * OS X doesn't see the NOP operation there. */ if (idx) { - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + if (needs_legacy_glsl_syntax(gl_info) && shader->u.ps.declared_in_count > in_count) { sprintf(register_name, @@ -2234,7 +2800,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * } else { - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + if (needs_legacy_glsl_syntax(gl_info) && shader->u.ps.declared_in_count > in_count) { sprintf(register_name, "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])", @@ -2269,7 +2835,12 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * /* Relative addressing */ if (reg->idx[0].rel_addr) { - if (reg->idx[0].offset) + if (wined3d_settings.check_float_constants) + sprintf(register_name, "(%s + %u >= 0 && %s + %u < %u ? %s_c[%s + %u] : vec4(0.0))", + rel_param0.param_str, reg->idx[0].offset, + rel_param0.param_str, reg->idx[0].offset, shader->limits->constant_float, + prefix, rel_param0.param_str, reg->idx[0].offset); + else if (reg->idx[0].offset) sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); else sprintf(register_name, "%s_c[%s]", prefix, rel_param0.param_str); @@ -2300,7 +2871,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_LOOP: - sprintf(register_name, "aL%u", ins->ctx->loop_state->current_reg - 1); + sprintf(register_name, "aL%u", ins->ctx->state->current_loop_reg - 1); break; case WINED3DSPR_SAMPLER: @@ -2312,7 +2883,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * WARN("Write to render target %u, only %d supported.\n", reg->idx[0].offset, gl_info->limits.buffers); - sprintf(register_name, "gl_FragData[%u]", reg->idx[0].offset); + sprintf(register_name, "%s[%u]", get_fragment_output(gl_info), reg->idx[0].offset); break; case WINED3DSPR_RASTOUT: @@ -2333,8 +2904,10 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * case WINED3DSPR_TEXCRDOUT: /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */ if (reg->idx[0].rel_addr) - FIXME("VS3 output registers relative addressing.\n"); - sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset); + sprintf(register_name, "%s_out[%s + %u]", + prefix, rel_param0.param_str, reg->idx[0].offset); + else + sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset); break; case WINED3DSPR_MISCTYPE: @@ -2363,15 +2936,18 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * switch (reg->data_type) { case WINED3D_DATA_FLOAT: - wined3d_ftoa(*(const float *)reg->immconst_data, register_name); + if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) + sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]); + else + wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name); break; case WINED3D_DATA_INT: - sprintf(register_name, "%#x", reg->immconst_data[0]); + sprintf(register_name, "%#x", reg->u.immconst_data[0]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: - sprintf(register_name, "%#xu", reg->immconst_data[0]); + sprintf(register_name, "%#xu", reg->u.immconst_data[0]); break; default: sprintf(register_name, "", reg->data_type); @@ -2383,24 +2959,33 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * switch (reg->data_type) { case WINED3D_DATA_FLOAT: - wined3d_ftoa(*(const float *)®->immconst_data[0], imm_str[0]); - wined3d_ftoa(*(const float *)®->immconst_data[1], imm_str[1]); - wined3d_ftoa(*(const float *)®->immconst_data[2], imm_str[2]); - wined3d_ftoa(*(const float *)®->immconst_data[3], imm_str[3]); - sprintf(register_name, "vec4(%s, %s, %s, %s)", - imm_str[0], imm_str[1], imm_str[2], imm_str[3]); + if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) + { + sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))", + reg->u.immconst_data[0], reg->u.immconst_data[1], + reg->u.immconst_data[2], reg->u.immconst_data[3]); + } + else + { + wined3d_ftoa(*(const float *)®->u.immconst_data[0], imm_str[0]); + wined3d_ftoa(*(const float *)®->u.immconst_data[1], imm_str[1]); + wined3d_ftoa(*(const float *)®->u.immconst_data[2], imm_str[2]); + wined3d_ftoa(*(const float *)®->u.immconst_data[3], imm_str[3]); + sprintf(register_name, "vec4(%s, %s, %s, %s)", + imm_str[0], imm_str[1], imm_str[2], imm_str[3]); + } break; case WINED3D_DATA_INT: sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)", - reg->immconst_data[0], reg->immconst_data[1], - reg->immconst_data[2], reg->immconst_data[3]); + reg->u.immconst_data[0], reg->u.immconst_data[1], + reg->u.immconst_data[2], reg->u.immconst_data[3]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)", - reg->immconst_data[0], reg->immconst_data[1], - reg->immconst_data[2], reg->immconst_data[3]); + reg->u.immconst_data[0], reg->u.immconst_data[1], + reg->u.immconst_data[2], reg->u.immconst_data[3]); break; default: sprintf(register_name, "", reg->data_type); @@ -2430,7 +3015,85 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_PRIMID: - sprintf(register_name, "uint(gl_PrimitiveIDIn)"); + if (version->type == WINED3D_SHADER_TYPE_GEOMETRY) + sprintf(register_name, "gl_PrimitiveIDIn"); + else + sprintf(register_name, "gl_PrimitiveID"); + break; + + case WINED3DSPR_IDXTEMP: + if (reg->idx[1].rel_addr) + sprintf(register_name, "X%u[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); + else + sprintf(register_name, "X%u[%u]", reg->idx[0].offset, reg->idx[1].offset); + break; + + case WINED3DSPR_LOCALTHREADINDEX: + if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) + sprintf(register_name, "int(gl_LocalInvocationIndex)"); + else + sprintf(register_name, "ivec2(gl_LocalInvocationIndex, 0)"); + break; + + case WINED3DSPR_GSINSTID: + case WINED3DSPR_OUTPOINTID: + if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) + sprintf(register_name, "gl_InvocationID"); + else + sprintf(register_name, "ivec2(gl_InvocationID, 0)"); + break; + + case WINED3DSPR_THREADID: + sprintf(register_name, "ivec3(gl_GlobalInvocationID)"); + break; + + case WINED3DSPR_THREADGROUPID: + sprintf(register_name, "ivec3(gl_WorkGroupID)"); + break; + + case WINED3DSPR_LOCALTHREADID: + sprintf(register_name, "ivec3(gl_LocalInvocationID)"); + break; + + case WINED3DSPR_FORKINSTID: + case WINED3DSPR_JOININSTID: + sprintf(register_name, "phase_instance_id"); + break; + + case WINED3DSPR_TESSCOORD: + sprintf(register_name, "gl_TessCoord"); + break; + + case WINED3DSPR_OUTCONTROLPOINT: + if (reg->idx[0].rel_addr) + { + if (reg->idx[1].rel_addr) + sprintf(register_name, "shader_out[%s + %u].reg[%s + %u]", + rel_param0.param_str, reg->idx[0].offset, + rel_param1.param_str, reg->idx[1].offset); + else + sprintf(register_name, "shader_out[%s + %u].reg[%u]", + rel_param0.param_str, reg->idx[0].offset, + reg->idx[1].offset); + } + else if (reg->idx[1].rel_addr) + { + sprintf(register_name, "shader_out[%u].reg[%s + %u]", + reg->idx[0].offset, rel_param1.param_str, + reg->idx[1].offset); + } + else + { + sprintf(register_name, "shader_out[%u].reg[%u]", + reg->idx[0].offset, reg->idx[1].offset); + } + break; + + case WINED3DSPR_PATCHCONST: + if (version->type == WINED3D_SHADER_TYPE_HULL) + sprintf(register_name, "hs_out[%u]", reg->idx[0].offset); + else + sprintf(register_name, "vpc[%u]", reg->idx[0].offset); break; default: @@ -2468,7 +3131,8 @@ static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *p return mask; } -static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask) { +static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask) +{ unsigned int size = 0; if (write_mask & WINED3DSP_WRITEMASK_0) ++size; @@ -2479,19 +3143,27 @@ static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask) { return size; } -static void shader_glsl_swizzle_to_str(const DWORD swizzle, BOOL fixup, DWORD mask, char *str) +static unsigned int shader_glsl_swizzle_get_component(DWORD swizzle, + unsigned int component_idx) +{ + /* swizzle bits fields: wwzzyyxx */ + return (swizzle >> (2 * component_idx)) & 0x3; +} + +static void shader_glsl_swizzle_to_str(DWORD swizzle, BOOL fixup, DWORD mask, char *str) { /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra", * but addressed as "rgba". To fix this we need to swap the register's x * and z components. */ const char *swizzle_chars = fixup ? "zyxw" : "xyzw"; + unsigned int i; *str++ = '.'; - /* swizzle bits fields: wwzzyyxx */ - if (mask & WINED3DSP_WRITEMASK_0) *str++ = swizzle_chars[swizzle & 0x03]; - if (mask & WINED3DSP_WRITEMASK_1) *str++ = swizzle_chars[(swizzle >> 2) & 0x03]; - if (mask & WINED3DSP_WRITEMASK_2) *str++ = swizzle_chars[(swizzle >> 4) & 0x03]; - if (mask & WINED3DSP_WRITEMASK_3) *str++ = swizzle_chars[(swizzle >> 6) & 0x03]; + for (i = 0; i < 4; ++i) + { + if (mask & (WINED3DSP_WRITEMASK_0 << i)) + *str++ = swizzle_chars[shader_glsl_swizzle_get_component(swizzle, i)]; + } *str = '\0'; } @@ -2504,12 +3176,58 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str); } +static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param, + enum wined3d_data_type dst_data_type, enum wined3d_data_type src_data_type) +{ + if (dst_data_type == src_data_type) + { + string_buffer_sprintf(dst_param, "%s", src_param); + return; + } + + if (src_data_type == WINED3D_DATA_FLOAT) + { + switch (dst_data_type) + { + case WINED3D_DATA_INT: + string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param); + return; + case WINED3D_DATA_RESOURCE: + case WINED3D_DATA_SAMPLER: + case WINED3D_DATA_UINT: + string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param); + return; + default: + break; + } + } + + if (src_data_type == WINED3D_DATA_UINT && dst_data_type == WINED3D_DATA_FLOAT) + { + string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param); + return; + } + + if (src_data_type == WINED3D_DATA_INT && dst_data_type == WINED3D_DATA_FLOAT) + { + string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param); + return; + } + + FIXME("Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type); + string_buffer_sprintf(dst_param, "%s", src_param); +} + /* From a given parameter token, generate the corresponding GLSL string. * Also, return the actual register name and swizzle in case the * caller needs this information as well. */ -static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, - const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src) +static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instruction *ins, + const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src, + enum wined3d_data_type data_type) { + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *reg_name = string_buffer_get(priv->string_buffers); + enum wined3d_data_type param_data_type; BOOL is_color = FALSE; char swizzle_str[6]; @@ -2520,35 +3238,37 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i shader_glsl_get_register_name(&wined3d_src->reg, glsl_src->reg_name, &is_color, ins); shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str); - if (wined3d_src->reg.type == WINED3DSPR_IMMCONST || wined3d_src->reg.type == WINED3DSPR_PRIMID) + switch (wined3d_src->reg.type) { - shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, glsl_src->param_str); + case WINED3DSPR_IMMCONST: + param_data_type = data_type; + break; + case WINED3DSPR_FORKINSTID: + case WINED3DSPR_GSINSTID: + case WINED3DSPR_JOININSTID: + case WINED3DSPR_LOCALTHREADID: + case WINED3DSPR_LOCALTHREADINDEX: + case WINED3DSPR_OUTPOINTID: + case WINED3DSPR_PRIMID: + case WINED3DSPR_THREADGROUPID: + case WINED3DSPR_THREADID: + param_data_type = WINED3D_DATA_INT; + break; + default: + param_data_type = WINED3D_DATA_FLOAT; + break; } - else - { - char reg_name[200]; - switch (wined3d_src->reg.data_type) - { - case WINED3D_DATA_FLOAT: - sprintf(reg_name, "%s", glsl_src->reg_name); - break; - case WINED3D_DATA_INT: - sprintf(reg_name, "floatBitsToInt(%s)", glsl_src->reg_name); - break; - case WINED3D_DATA_RESOURCE: - case WINED3D_DATA_SAMPLER: - case WINED3D_DATA_UINT: - sprintf(reg_name, "floatBitsToUint(%s)", glsl_src->reg_name); - break; - default: - FIXME("Unhandled data type %#x.\n", wined3d_src->reg.data_type); - sprintf(reg_name, "%s", glsl_src->reg_name); - break; - } + shader_glsl_sprintf_cast(reg_name, glsl_src->reg_name, data_type, param_data_type); + shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name->buffer, swizzle_str, glsl_src->param_str); - shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name, swizzle_str, glsl_src->param_str); - } + string_buffer_release(priv->string_buffers, reg_name); +} + +static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, + const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src) +{ + shader_glsl_add_src_param_ext(ins, wined3d_src, mask, glsl_src, wined3d_src->reg.data_type); } /* From a given parameter token, generate the corresponding GLSL string. @@ -2656,42 +3376,43 @@ static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op) } } -static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, - DWORD resource_idx, DWORD flags, struct glsl_sample_function *sample_function) +static BOOL shader_glsl_has_core_grad(const struct wined3d_gl_info *gl_info) +{ + return shader_glsl_get_version(gl_info) >= 130 || gl_info->supported[EXT_GPU_SHADER4]; +} + +static void shader_glsl_get_coord_size(enum wined3d_shader_resource_type resource_type, + unsigned int *coord_size, unsigned int *deriv_size) +{ + const BOOL is_array = resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY + || resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY; + + *coord_size = resource_type_info[resource_type].coord_size; + *deriv_size = *coord_size; + if (is_array) + --(*deriv_size); +} + +static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, + DWORD resource_idx, DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function) { - static const struct - { - unsigned int coord_size; - const char *type_part; - } - resource_types[] = - { - {0, ""}, /* WINED3D_SHADER_RESOURCE_NONE */ - {1, ""}, /* WINED3D_SHADER_RESOURCE_BUFFER */ - {1, "1D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ - {2, "2D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ - {2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ - {3, "3D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ - {3, "Cube"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ - {2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ - {3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ - {3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ - }; - struct shader_glsl_ctx_priv *priv = ctx->backend_data; enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; + struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = ctx->gl_info; - BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL - && (priv->cur_ps_args->shadow & (1u << resource_idx)); + BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; - BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE]; + BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL + && priv->cur_ps_args->np2_fixup & (1u << resource_idx) + && gl_info->supported[ARB_TEXTURE_RECTANGLE]; BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD; + BOOL offset = flags & WINED3D_GLSL_SAMPLE_OFFSET; const char *base = "texture", *type_part = "", *suffix = ""; - unsigned int coord_size; + unsigned int coord_size, deriv_size; sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type; - if (resource_type >= ARRAY_SIZE(resource_types)) + if (resource_type >= ARRAY_SIZE(resource_type_info)) { ERR("Unexpected resource type %#x.\n", resource_type); resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; @@ -2706,13 +3427,13 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (shadow) base = "shadow"; - type_part = resource_types[resource_type].type_part; + type_part = resource_type_info[resource_type].type_part; if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D && texrect) type_part = "2DRect"; - if (!type_part[0]) + if (!type_part[0] && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY) FIXME("Unhandled resource type %#x.\n", resource_type); - if (!lod && grad && !gl_info->supported[EXT_GPU_SHADER4]) + if (!lod && grad && !shader_glsl_has_core_grad(gl_info)) { if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) suffix = "ARB"; @@ -2723,21 +3444,24 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (flags & WINED3D_GLSL_SAMPLE_LOAD) { - if (flags != WINED3D_GLSL_SAMPLE_LOAD) - ERR("Unexpected flags for texelFetch %#x.\n", flags & ~WINED3D_GLSL_SAMPLE_LOAD); + static const DWORD texel_fetch_flags = WINED3D_GLSL_SAMPLE_LOAD | WINED3D_GLSL_SAMPLE_OFFSET; + if (flags & ~texel_fetch_flags) + ERR("Unexpected flags %#x for texelFetch.\n", flags & ~texel_fetch_flags); base = "texelFetch"; type_part = ""; } sample_function->name = string_buffer_get(priv->string_buffers); - string_buffer_sprintf(sample_function->name, "%s%s%s%s%s", base, type_part, projected ? "Proj" : "", - lod ? "Lod" : grad ? "Grad" : "", suffix); + string_buffer_sprintf(sample_function->name, "%s%s%s%s%s%s", base, type_part, projected ? "Proj" : "", + lod ? "Lod" : grad ? "Grad" : "", offset ? "Offset" : "", suffix); - coord_size = resource_types[resource_type].coord_size; + shader_glsl_get_coord_size(resource_type, &coord_size, &deriv_size); if (shadow) ++coord_size; + sample_function->offset_size = offset ? deriv_size : 0; sample_function->coord_mask = (1u << coord_size) - 1; + sample_function->deriv_mask = (1u << deriv_size) - 1; sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info); } @@ -2854,9 +3578,10 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name, ins->dst[0].write_mask, fixup); } -static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, +static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, DWORD swizzle, - const char *dx, const char *dy, const char *bias, const char *coord_reg_fmt, ...) + const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset, + const char *coord_reg_fmt, ...) { const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; char dst_swizzle[6]; @@ -2867,9 +3592,8 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle); - /* FIXME: We currently don't support fixups for vertex shaders or anything - * above SM3. Note that for SM4+ the sampler index doesn't have to match - * the resource index. */ + /* If ARB_texture_swizzle is supported we don't need to do anything here. + * We actually rely on it for vertex shaders and SM4+. */ if (version->type == WINED3D_SHADER_TYPE_PIXEL && version->major < 4) { const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; @@ -2928,11 +3652,16 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s } } if (dx && dy) - shader_addline(ins->ctx->buffer, ", %s, %s)", dx, dy); + shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) - shader_addline(ins->ctx->buffer, ", %s)", bias); - else - shader_addline(ins->ctx->buffer, ")"); + shader_addline(ins->ctx->buffer, ", %s", bias); + if (sample_function->offset_size) + { + int offset_immdata[4] = {offset->u, offset->v, offset->w}; + shader_addline(ins->ctx->buffer, ", "); + shader_glsl_append_imm_ivec(ins->ctx->buffer, offset_immdata, sample_function->offset_size); + } + shader_addline(ins->ctx->buffer, ")"); if (sample_function->output_single_component) shader_addline(ins->ctx->buffer, ")"); @@ -2943,6 +3672,28 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s shader_glsl_color_correction(ins, fixup); } +static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer) +{ + /* Write the final position. + * + * OpenGL coordinates specify the center of the pixel while D3D coords + * specify the corner. The offsets are stored in z and w in + * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering + * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow + * a MAD. */ + shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n"); + shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n"); + + /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix() + * in utils.c + * + * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, + * shaders are run before the homogeneous divide, so we have to take the w + * into account: z = ((z / w) * 2 - 1) * w, which is the same as + * z = z * 2 - w. */ + shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); +} + /***************************************************************************** * Begin processing individual instruction opcodes ****************************************************************************/ @@ -2963,6 +3714,7 @@ static void shader_glsl_binop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_DIV: op = "/"; break; case WINED3DSIH_IADD: op = "+"; break; case WINED3DSIH_ISHL: op = "<<"; break; + case WINED3DSIH_ISHR: op = ">>"; break; case WINED3DSIH_MUL: op = "*"; break; case WINED3DSIH_OR: op = "|"; break; case WINED3DSIH_SUB: op = "-"; break; @@ -3005,6 +3757,7 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_UGE: op = "greaterThanEqual"; break; case WINED3DSIH_LT: op = "lessThan"; break; case WINED3DSIH_ILT: op = "lessThan"; break; + case WINED3DSIH_ULT: op = "lessThan"; break; case WINED3DSIH_NE: op = "notEqual"; break; case WINED3DSIH_INE: op = "notEqual"; break; default: @@ -3027,6 +3780,7 @@ static void shader_glsl_relop(const struct wined3d_shader_instruction *ins) case WINED3DSIH_UGE: op = ">="; break; case WINED3DSIH_LT: op = "<"; break; case WINED3DSIH_ILT: op = "<"; break; + case WINED3DSIH_ULT: op = "<"; break; case WINED3DSIH_NE: op = "!="; break; case WINED3DSIH_INE: op = "!="; break; default: @@ -3062,15 +3816,15 @@ static void shader_glsl_unary_op(const struct wined3d_shader_instruction *ins) shader_addline(ins->ctx->buffer, "%s%s);\n", op, src_param.param_str); } -static void shader_glsl_imul(const struct wined3d_shader_instruction *ins) +static void shader_glsl_mul_extended(const struct wined3d_shader_instruction *ins) { struct wined3d_string_buffer *buffer = ins->ctx->buffer; struct glsl_src_param src0_param; struct glsl_src_param src1_param; DWORD write_mask; - /* If we have ARB_gpu_shader5 or GLSL 4.0, we can use imulExtended(). If - * not, we can emulate it. */ + /* If we have ARB_gpu_shader5, we can use imulExtended() / umulExtended(). + * If not, we can emulate it. */ if (ins->dst[0].reg.type != WINED3DSPR_NULL) FIXME("64-bit integer multiplies not implemented.\n"); @@ -3153,12 +3907,11 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "int(floor(%s)));\n", src0_param.param_str); } } - else if(ins->handler_idx == WINED3DSIH_MOVA) + else if (ins->handler_idx == WINED3DSIH_MOVA) { - /* We need to *round* to the nearest int here. */ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask); - if (gl_info->supported[EXT_GPU_SHADER4]) + if (shader_glsl_get_version(gl_info) >= 130 || gl_info->supported[EXT_GPU_SHADER4]) { if (mask_size > 1) shader_addline(buffer, "ivec%d(round(%s)));\n", mask_size, src0_param.param_str); @@ -3229,7 +3982,12 @@ static void shader_glsl_cross(const struct wined3d_shader_instruction *ins) static void shader_glsl_cut(const struct wined3d_shader_instruction *ins) { - shader_addline(ins->ctx->buffer, "EndPrimitive();\n"); + unsigned int stream = ins->handler_idx == WINED3DSIH_CUT ? 0 : ins->src[0].reg.idx[0].offset; + + if (!stream) + shader_addline(ins->ctx->buffer, "EndPrimitive();\n"); + else + FIXME("Unhandled primitive stream %u.\n", stream); } /* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1) @@ -3275,24 +4033,39 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) switch (ins->handler_idx) { case WINED3DSIH_ABS: instruction = "abs"; break; + case WINED3DSIH_BFREV: instruction = "bitfieldReverse"; break; + case WINED3DSIH_COUNTBITS: instruction = "bitCount"; break; case WINED3DSIH_DSX: instruction = "dFdx"; break; + case WINED3DSIH_DSX_COARSE: instruction = "dFdxCoarse"; break; + case WINED3DSIH_DSX_FINE: instruction = "dFdxFine"; break; case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break; + case WINED3DSIH_DSY_COARSE: instruction = "ycorrection.y * dFdyCoarse"; break; + case WINED3DSIH_DSY_FINE: instruction = "ycorrection.y * dFdyFine"; break; + case WINED3DSIH_FIRSTBIT_HI: instruction = "findMSB"; break; + case WINED3DSIH_FIRSTBIT_LO: instruction = "findLSB"; break; + case WINED3DSIH_FIRSTBIT_SHI: instruction = "findMSB"; break; case WINED3DSIH_FRC: instruction = "fract"; break; case WINED3DSIH_IMAX: instruction = "max"; break; case WINED3DSIH_IMIN: instruction = "min"; break; case WINED3DSIH_MAX: instruction = "max"; break; case WINED3DSIH_MIN: instruction = "min"; break; + case WINED3DSIH_ROUND_NE: instruction = "roundEven"; break; case WINED3DSIH_ROUND_NI: instruction = "floor"; break; case WINED3DSIH_ROUND_PI: instruction = "ceil"; break; case WINED3DSIH_ROUND_Z: instruction = "trunc"; break; case WINED3DSIH_SQRT: instruction = "sqrt"; break; + case WINED3DSIH_UMAX: instruction = "max"; break; + case WINED3DSIH_UMIN: instruction = "min"; break; default: instruction = ""; - FIXME("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); + ERR("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } write_mask = shader_glsl_append_dst(buffer, ins); + /* In D3D bits are numbered from the most significant bit. */ + if (ins->handler_idx == WINED3DSIH_FIRSTBIT_HI || ins->handler_idx == WINED3DSIH_FIRSTBIT_SHI) + shader_addline(buffer, "31 - "); shader_addline(buffer, "%s(", instruction); if (ins->src_count) @@ -3309,6 +4082,66 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "));\n"); } +static void shader_glsl_float16(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_shader_dst_param dst; + struct glsl_src_param src; + DWORD write_mask; + const char *fmt; + unsigned int i; + + fmt = ins->handler_idx == WINED3DSIH_F16TOF32 + ? "unpackHalf2x16(%s).x);\n" : "packHalf2x16(vec2(%s, 0.0)));\n"; + + dst = ins->dst[0]; + for (i = 0; i < 4; ++i) + { + dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i); + if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, + &dst, dst.reg.data_type))) + continue; + + shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src); + shader_addline(ins->ctx->buffer, fmt, src.param_str); + } +} + +static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct wined3d_shader_dst_param dst; + struct glsl_src_param src[4]; + const char *instruction; + unsigned int i, j; + DWORD write_mask; + + switch (ins->handler_idx) + { + case WINED3DSIH_BFI: instruction = "bitfieldInsert"; break; + case WINED3DSIH_IBFE: instruction = "bitfieldExtract"; break; + case WINED3DSIH_UBFE: instruction = "bitfieldExtract"; break; + default: + ERR("Unhandled opcode %#x.\n", ins->handler_idx); + return; + } + + dst = ins->dst[0]; + for (i = 0; i < 4; ++i) + { + dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i); + if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, + &dst, dst.reg.data_type))) + continue; + + for (j = 0; j < ins->src_count; ++j) + shader_glsl_add_src_param(ins, &ins->src[j], write_mask, &src[j]); + shader_addline(buffer, "%s(", instruction); + for (j = 0; j < ins->src_count - 2; ++j) + shader_addline(buffer, "%s, ", src[ins->src_count - j - 1].param_str); + shader_addline(buffer, "%s & 0x1f, %s & 0x1f));\n", src[1].param_str, src[0].param_str); + } +} + static void shader_glsl_nop(const struct wined3d_shader_instruction *ins) {} static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) @@ -3580,7 +4413,7 @@ static void shader_glsl_conditional_move(const struct wined3d_shader_instruction /* Find the destination channels which use the current source0 channel. */ for (j = 0; j < 4; ++j) { - if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i) + if (shader_glsl_swizzle_get_component(ins->src[0].swizzle, j) == i) { write_mask |= WINED3DSP_WRITEMASK_0 << j; cmp_channel = WINED3DSP_WRITEMASK_0 << j; @@ -3917,7 +4750,7 @@ static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins) /* FIXME: I don't think nested loops will work correctly this way. */ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins) { - struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state; + struct wined3d_shader_parser_state *state = ins->ctx->state; struct wined3d_string_buffer *buffer = ins->ctx->buffer; const struct wined3d_shader *shader = ins->ctx->shader; const struct wined3d_shader_lconst *constant; @@ -3955,65 +4788,65 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins) if (loop_control.step > 0) { shader_addline(buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d)\n{\n", - loop_state->current_depth, loop_control.start, - loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start, - loop_state->current_depth, loop_control.step); + state->current_loop_depth, loop_control.start, + state->current_loop_depth, loop_control.count, loop_control.step, loop_control.start, + state->current_loop_depth, loop_control.step); } else if (loop_control.step < 0) { shader_addline(buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d)\n{\n", - loop_state->current_depth, loop_control.start, - loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start, - loop_state->current_depth, loop_control.step); + state->current_loop_depth, loop_control.start, + state->current_loop_depth, loop_control.count, loop_control.step, loop_control.start, + state->current_loop_depth, loop_control.step); } else { shader_addline(buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++)\n{\n", - loop_state->current_depth, loop_control.start, loop_state->current_depth, - loop_state->current_depth, loop_control.count, - loop_state->current_depth); + state->current_loop_depth, loop_control.start, state->current_loop_depth, + state->current_loop_depth, loop_control.count, + state->current_loop_depth); } } else { shader_addline(buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z)\n{\n", - loop_state->current_depth, loop_state->current_reg, - src1_param.reg_name, loop_state->current_depth, src1_param.reg_name, - loop_state->current_depth, loop_state->current_reg, src1_param.reg_name); + state->current_loop_depth, state->current_loop_reg, + src1_param.reg_name, state->current_loop_depth, src1_param.reg_name, + state->current_loop_depth, state->current_loop_reg, src1_param.reg_name); } - ++loop_state->current_reg; + ++state->current_loop_reg; } else { shader_addline(buffer, "for (;;)\n{\n"); } - ++loop_state->current_depth; + ++state->current_loop_depth; } static void shader_glsl_end(const struct wined3d_shader_instruction *ins) { - struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state; + struct wined3d_shader_parser_state *state = ins->ctx->state; shader_addline(ins->ctx->buffer, "}\n"); if (ins->handler_idx == WINED3DSIH_ENDLOOP) { - --loop_state->current_depth; - --loop_state->current_reg; + --state->current_loop_depth; + --state->current_loop_reg; } if (ins->handler_idx == WINED3DSIH_ENDREP) { - --loop_state->current_depth; + --state->current_loop_depth; } } static void shader_glsl_rep(const struct wined3d_shader_instruction *ins) { + struct wined3d_shader_parser_state *state = ins->ctx->state; const struct wined3d_shader *shader = ins->ctx->shader; - struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state; const struct wined3d_shader_lconst *constant; struct glsl_src_param src0_param; const DWORD *control_values = NULL; @@ -4034,26 +4867,48 @@ static void shader_glsl_rep(const struct wined3d_shader_instruction *ins) if (control_values) { shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n", - loop_state->current_depth, loop_state->current_depth, - control_values[0], loop_state->current_depth); + state->current_loop_depth, state->current_loop_depth, + control_values[0], state->current_loop_depth); } else { shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n", - loop_state->current_depth, loop_state->current_depth, - src0_param.param_str, loop_state->current_depth); + state->current_loop_depth, state->current_loop_depth, + src0_param.param_str, state->current_loop_depth); } - ++loop_state->current_depth; + ++state->current_loop_depth; } -static void shader_glsl_if(const struct wined3d_shader_instruction *ins) +static void shader_glsl_switch(const struct wined3d_shader_instruction *ins) { struct glsl_src_param src0_param; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); - shader_addline(ins->ctx->buffer, "if (bool(%s)) {\n", src0_param.param_str); + shader_addline(ins->ctx->buffer, "switch (%s)\n{\n", src0_param.param_str); +} + +static void shader_glsl_case(const struct wined3d_shader_instruction *ins) +{ + struct glsl_src_param src0_param; + + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); + shader_addline(ins->ctx->buffer, "case %s:\n", src0_param.param_str); +} + +static void shader_glsl_default(const struct wined3d_shader_instruction *ins) +{ + shader_addline(ins->ctx->buffer, "default:\n"); +} + +static void shader_glsl_if(const struct wined3d_shader_instruction *ins) +{ + const char *condition = (ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ) ? "bool" : "!bool"; + struct glsl_src_param src0_param; + + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); + shader_addline(ins->ctx->buffer, "if (%s(%s)) {\n", condition, src0_param.param_str); } static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins) @@ -4075,7 +4930,16 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins) static void shader_glsl_emit(const struct wined3d_shader_instruction *ins) { - shader_addline(ins->ctx->buffer, "EmitVertex();\n"); + unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset; + + shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n"); + if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL]) + shader_glsl_fixup_position(ins->ctx->buffer); + + if (!stream) + shader_addline(ins->ctx->buffer, "EmitVertex();\n"); + else + FIXME("Unhandled primitive stream %u.\n", stream); } static void shader_glsl_break(const struct wined3d_shader_instruction *ins) @@ -4096,18 +4960,38 @@ static void shader_glsl_breakc(const struct wined3d_shader_instruction *ins) src0_param.param_str, shader_glsl_get_rel_op(ins->flags), src1_param.param_str); } -static void shader_glsl_breakp(const struct wined3d_shader_instruction *ins) +static void shader_glsl_conditional_op(const struct wined3d_shader_instruction *ins) { + const char *condition = (ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ) ? "bool" : "!bool"; struct glsl_src_param src_param; + const char *op; + + switch (ins->handler_idx) + { + case WINED3DSIH_BREAKP: op = "break"; break; + case WINED3DSIH_CONTINUEP: op = "continue"; break; + case WINED3DSIH_RETP: op = "return"; break; + default: + ERR("Unhandled opcode %#x.\n", ins->handler_idx); + return; + } shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param); - shader_addline(ins->ctx->buffer, "if (bool(%s)) break;\n", src_param.param_str); + shader_addline(ins->ctx->buffer, "if (%s(%s)) %s;\n", condition, src_param.param_str, op); +} + +static void shader_glsl_continue(const struct wined3d_shader_instruction *ins) +{ + shader_addline(ins->ctx->buffer, "continue;\n"); } static void shader_glsl_label(const struct wined3d_shader_instruction *ins) { shader_addline(ins->ctx->buffer, "}\n"); shader_addline(ins->ctx->buffer, "void subroutine%u()\n{\n", ins->src[0].reg.idx[0].offset); + + /* Subroutines appear at the end of the shader. */ + ins->ctx->state->in_subroutine = TRUE; } static void shader_glsl_call(const struct wined3d_shader_instruction *ins) @@ -4126,14 +5010,15 @@ static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins) static void shader_glsl_ret(const struct wined3d_shader_instruction *ins) { - /* No-op. The closing } is written when a new function is started, and at the end of the shader. This - * function only suppresses the unhandled instruction warning - */ + const struct wined3d_shader_version *version = &ins->ctx->shader->reg_maps.shader_version; + + if (version->major >= 4 && !ins->ctx->state->in_subroutine) + { + shader_glsl_generate_shader_epilogue(ins->ctx); + shader_addline(ins->ctx->buffer, "return;\n"); + } } -/********************************************* - * Pixel Shader Specific Code begins here - ********************************************/ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) { DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, @@ -4202,10 +5087,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) } } - if (priv->cur_ps_args->np2_fixup & (1u << resource_idx)) - sample_flags |= WINED3D_GLSL_SAMPLE_NPOT; - - shader_glsl_get_sample_function(ins->ctx, resource_idx, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, resource_idx, resource_idx, sample_flags, &sample_function); mask |= sample_function.coord_mask; sample_function.coord_mask = mask; @@ -4218,7 +5100,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) { char coord_mask[6]; shader_glsl_write_mask_to_str(mask, coord_mask); - shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL, "T%u%s", resource_idx, coord_mask); } else @@ -4230,9 +5112,9 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) struct glsl_src_param bias; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias); shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str, - "%s", coord_param.param_str); + NULL, "%s", coord_param.param_str); } else { - shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL, "%s", coord_param.param_str); } } @@ -4243,62 +5125,54 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) { const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; struct glsl_src_param coord_param, dx_param, dy_param; - DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD; struct glsl_sample_function sample_function; DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; - const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; - if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4]) + if (!shader_glsl_has_core_grad(gl_info) && !gl_info->supported[ARB_SHADER_TEXTURE_LOD]) { - FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n"); + FIXME("texldd used, but not supported by hardware. Falling back to regular tex.\n"); shader_glsl_tex(ins); return; } sampler_idx = ins->src[1].reg.idx[0].offset; - if (priv->cur_ps_args->np2_fixup & (1u << sampler_idx)) - sample_flags |= WINED3D_GLSL_SAMPLE_NPOT; - shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_GRAD, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); - shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param); - shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param); + shader_glsl_add_src_param(ins, &ins->src[2], sample_function.deriv_mask, &dx_param); + shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dy_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL, - "%s", coord_param.param_str); + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, + NULL, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_version *shader_version = &ins->ctx->reg_maps->shader_version; const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; struct glsl_src_param coord_param, lod_param; - DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD; struct glsl_sample_function sample_function; - DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; - const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + DWORD sampler_idx; sampler_idx = ins->src[1].reg.idx[0].offset; - if (ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL - && priv->cur_ps_args->np2_fixup & (1u << sampler_idx)) - sample_flags |= WINED3D_GLSL_SAMPLE_NPOT; - shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_LOD, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param); - if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4] - && ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL) + if (shader_version->type == WINED3D_SHADER_TYPE_PIXEL && !shader_glsl_has_core_grad(gl_info) + && !gl_info->supported[ARB_SHADER_TEXTURE_LOD]) { /* Plain GLSL only supports Lod sampling functions in vertex shaders. * However, the NVIDIA drivers allow them in fragment shaders as well, * even without the appropriate extension. */ WARN("Using %s in fragment shader.\n", sample_function.name->buffer); } - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4320,26 +5194,503 @@ static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler return ~0u; } +static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins) +{ + const BOOL is_imm_instruction = WINED3DSIH_IMM_ATOMIC_AND <= ins->handler_idx + && ins->handler_idx <= WINED3DSIH_IMM_ATOMIC_XOR; + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct glsl_src_param structure_idx, offset, data, data2; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + enum wined3d_shader_resource_type resource_type; + struct wined3d_string_buffer *address; + enum wined3d_data_type data_type; + unsigned int resource_idx, stride; + const char *op, *resource; + DWORD coord_mask; + BOOL is_tgsm; + + resource_idx = ins->dst[is_imm_instruction].reg.idx[0].offset; + is_tgsm = ins->dst[is_imm_instruction].reg.type == WINED3DSPR_GROUPSHAREDMEM; + if (is_tgsm) + { + if (resource_idx >= reg_maps->tgsm_count) + { + ERR("Invalid TGSM index %u.\n", resource_idx); + return; + } + resource = "g"; + data_type = WINED3D_DATA_UINT; + coord_mask = 1; + stride = reg_maps->tgsm[resource_idx].stride; + } + else + { + if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", resource_idx); + return; + } + resource_type = reg_maps->uav_resource_info[resource_idx].type; + if (resource_type >= ARRAY_SIZE(resource_type_info)) + { + ERR("Unexpected resource type %#x.\n", resource_type); + return; + } + resource = "image"; + data_type = reg_maps->uav_resource_info[resource_idx].data_type; + coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1; + stride = reg_maps->uav_resource_info[resource_idx].stride; + } + + switch (ins->handler_idx) + { + case WINED3DSIH_ATOMIC_AND: + case WINED3DSIH_IMM_ATOMIC_AND: + if (is_tgsm) + op = "atomicAnd"; + else + op = "imageAtomicAnd"; + break; + case WINED3DSIH_ATOMIC_CMP_STORE: + case WINED3DSIH_IMM_ATOMIC_CMP_EXCH: + if (is_tgsm) + op = "atomicCompSwap"; + else + op = "imageAtomicCompSwap"; + break; + case WINED3DSIH_ATOMIC_IADD: + case WINED3DSIH_IMM_ATOMIC_IADD: + if (is_tgsm) + op = "atomicAdd"; + else + op = "imageAtomicAdd"; + break; + case WINED3DSIH_ATOMIC_IMAX: + case WINED3DSIH_IMM_ATOMIC_IMAX: + if (is_tgsm) + op = "atomicMax"; + else + op = "imageAtomicMax"; + if (data_type != WINED3D_DATA_INT) + { + FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx); + return; + } + break; + case WINED3DSIH_ATOMIC_IMIN: + case WINED3DSIH_IMM_ATOMIC_IMIN: + if (is_tgsm) + op = "atomicMin"; + else + op = "imageAtomicMin"; + if (data_type != WINED3D_DATA_INT) + { + FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx); + return; + } + break; + case WINED3DSIH_ATOMIC_OR: + case WINED3DSIH_IMM_ATOMIC_OR: + if (is_tgsm) + op = "atomicOr"; + else + op = "imageAtomicOr"; + break; + case WINED3DSIH_ATOMIC_UMAX: + case WINED3DSIH_IMM_ATOMIC_UMAX: + if (is_tgsm) + op = "atomicMax"; + else + op = "imageAtomicMax"; + if (data_type != WINED3D_DATA_UINT) + { + FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx); + return; + } + break; + case WINED3DSIH_ATOMIC_UMIN: + case WINED3DSIH_IMM_ATOMIC_UMIN: + if (is_tgsm) + op = "atomicMin"; + else + op = "imageAtomicMin"; + if (data_type != WINED3D_DATA_UINT) + { + FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx); + return; + } + break; + case WINED3DSIH_ATOMIC_XOR: + case WINED3DSIH_IMM_ATOMIC_XOR: + if (is_tgsm) + op = "atomicXor"; + else + op = "imageAtomicXor"; + break; + case WINED3DSIH_IMM_ATOMIC_EXCH: + if (is_tgsm) + op = "atomicExchange"; + else + op = "imageAtomicExchange"; + break; + default: + ERR("Unhandled opcode %#x.\n", ins->handler_idx); + return; + } + + address = string_buffer_get(priv->string_buffers); + if (stride) + { + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &structure_idx); + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &offset); + string_buffer_sprintf(address, "%s * %u + %s / 4", structure_idx.param_str, stride, offset.param_str); + } + else + { + shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &offset); + string_buffer_sprintf(address, "%s", offset.param_str); + if (is_tgsm || (reg_maps->uav_resource_info[resource_idx].flags & WINED3D_VIEW_BUFFER_RAW)) + shader_addline(address, "/ 4"); + } + + if (is_imm_instruction) + shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], data_type); + + if (is_tgsm) + shader_addline(buffer, "%s(%s_%s%u[%s], ", + op, shader_glsl_get_prefix(version->type), resource, resource_idx, address->buffer); + else + shader_addline(buffer, "%s(%s_%s%u, %s, ", + op, shader_glsl_get_prefix(version->type), resource, resource_idx, address->buffer); + + shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &data, data_type); + shader_addline(buffer, "%s", data.param_str); + if (ins->src_count >= 3) + { + shader_glsl_add_src_param_ext(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &data2, data_type); + shader_addline(buffer, ", %s", data2.param_str); + } + + if (is_imm_instruction) + shader_addline(buffer, ")"); + shader_addline(buffer, ");\n"); + + string_buffer_release(priv->string_buffers, address); +} + +static void shader_glsl_uav_counter(const struct wined3d_shader_instruction *ins) +{ + const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type); + const char *op; + + if (ins->handler_idx == WINED3DSIH_IMM_ATOMIC_ALLOC) + op = "atomicCounterIncrement"; + else + op = "atomicCounterDecrement"; + + shader_glsl_append_dst(ins->ctx->buffer, ins); + shader_addline(ins->ctx->buffer, "%s(%s_counter%u));\n", op, prefix, ins->src[0].reg.idx[0].offset); +} + +static void shader_glsl_ld_uav(const struct wined3d_shader_instruction *ins) +{ + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; + enum wined3d_shader_resource_type resource_type; + struct glsl_src_param image_coord_param; + enum wined3d_data_type data_type; + DWORD coord_mask, write_mask; + unsigned int uav_idx; + char dst_swizzle[6]; + + uav_idx = ins->src[1].reg.idx[0].offset; + if (uav_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", uav_idx); + return; + } + resource_type = reg_maps->uav_resource_info[uav_idx].type; + if (resource_type >= ARRAY_SIZE(resource_type_info)) + { + ERR("Unexpected resource type %#x.\n", resource_type); + resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; + } + data_type = reg_maps->uav_resource_info[uav_idx].data_type; + coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1; + + write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], data_type); + shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle); + + shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &image_coord_param); + shader_addline(ins->ctx->buffer, "imageLoad(%s_image%u, %s)%s);\n", + shader_glsl_get_prefix(version->type), uav_idx, image_coord_param.param_str, dst_swizzle); +} + +static void shader_glsl_ld_raw_structured(const struct wined3d_shader_instruction *ins) +{ + const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type); + const struct wined3d_shader_src_param *src = &ins->src[ins->src_count - 1]; + unsigned int i, swizzle, resource_idx, bind_idx, stride, src_idx = 0; + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct glsl_src_param structure_idx, offset; + struct wined3d_string_buffer *address; + struct wined3d_shader_dst_param dst; + const char *function, *resource; + + resource_idx = src->reg.idx[0].offset; + if (src->reg.type == WINED3DSPR_RESOURCE) + { + if (resource_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", resource_idx); + return; + } + stride = reg_maps->resource_info[resource_idx].stride; + bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT); + function = "texelFetch"; + resource = "sampler"; + } + else if (src->reg.type == WINED3DSPR_UAV) + { + if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", resource_idx); + return; + } + stride = reg_maps->uav_resource_info[resource_idx].stride; + bind_idx = resource_idx; + function = "imageLoad"; + resource = "image"; + } + else + { + if (resource_idx >= reg_maps->tgsm_count) + { + ERR("Invalid TGSM index %u.\n", resource_idx); + return; + } + stride = reg_maps->tgsm[resource_idx].stride; + bind_idx = resource_idx; + function = NULL; + resource = "g"; + } + + address = string_buffer_get(priv->string_buffers); + if (ins->handler_idx == WINED3DSIH_LD_STRUCTURED) + { + shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &structure_idx); + shader_addline(address, "%s * %u + ", structure_idx.param_str, stride); + } + shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &offset); + shader_addline(address, "%s / 4", offset.param_str); + + dst = ins->dst[0]; + for (i = 0; i < 4; ++i) + { + dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i); + if (!shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst, dst.reg.data_type)) + continue; + + swizzle = shader_glsl_swizzle_get_component(src->swizzle, i); + if (function) + shader_addline(buffer, "%s(%s_%s%u, %s + %u).x);\n", + function, prefix, resource, bind_idx, address->buffer, swizzle); + else + shader_addline(buffer, "%s_%s%u[%s + %u]);\n", + prefix, resource, bind_idx, address->buffer, swizzle); + } + + string_buffer_release(priv->string_buffers, address); +} + +static void shader_glsl_store_uav(const struct wined3d_shader_instruction *ins) +{ + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; + struct glsl_src_param image_coord_param, image_data_param; + enum wined3d_shader_resource_type resource_type; + enum wined3d_data_type data_type; + unsigned int uav_idx; + DWORD coord_mask; + + uav_idx = ins->dst[0].reg.idx[0].offset; + if (uav_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", uav_idx); + return; + } + resource_type = reg_maps->uav_resource_info[uav_idx].type; + if (resource_type >= ARRAY_SIZE(resource_type_info)) + { + ERR("Unexpected resource type %#x.\n", resource_type); + return; + } + data_type = reg_maps->uav_resource_info[uav_idx].data_type; + coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1; + + shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &image_coord_param); + shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &image_data_param, data_type); + shader_addline(ins->ctx->buffer, "imageStore(%s_image%u, %s, %s);\n", + shader_glsl_get_prefix(version->type), uav_idx, + image_coord_param.param_str, image_data_param.param_str); +} + +static void shader_glsl_store_raw_structured(const struct wined3d_shader_instruction *ins) +{ + const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type); + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct glsl_src_param structure_idx, offset, data; + unsigned int i, resource_idx, stride, src_idx = 0; + struct wined3d_string_buffer *address; + DWORD write_mask; + BOOL is_tgsm; + + resource_idx = ins->dst[0].reg.idx[0].offset; + is_tgsm = ins->dst[0].reg.type == WINED3DSPR_GROUPSHAREDMEM; + if (is_tgsm) + { + if (resource_idx >= reg_maps->tgsm_count) + { + ERR("Invalid TGSM index %u.\n", resource_idx); + return; + } + stride = reg_maps->tgsm[resource_idx].stride; + } + else + { + if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", resource_idx); + return; + } + stride = reg_maps->uav_resource_info[resource_idx].stride; + } + + address = string_buffer_get(priv->string_buffers); + if (ins->handler_idx == WINED3DSIH_STORE_STRUCTURED) + { + shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &structure_idx); + shader_addline(address, "%s * %u + ", structure_idx.param_str, stride); + } + shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &offset); + shader_addline(address, "%s / 4", offset.param_str); + + for (i = 0; i < 4; ++i) + { + if (!(write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i))) + continue; + + shader_glsl_add_src_param(ins, &ins->src[src_idx], write_mask, &data); + + if (is_tgsm) + shader_addline(buffer, "%s_g%u[%s + %u] = %s;\n", + prefix, resource_idx, address->buffer, i, data.param_str); + else + shader_addline(buffer, "imageStore(%s_image%u, %s + %u, uvec4(%s, 0, 0, 0));\n", + prefix, resource_idx, address->buffer, i, data.param_str); + } + + string_buffer_release(priv->string_buffers, address); +} + +static void shader_glsl_sync(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + unsigned int sync_flags = ins->flags; + + if (sync_flags & WINED3DSSF_THREAD_GROUP) + { + shader_addline(buffer, "barrier();\n"); + sync_flags &= ~(WINED3DSSF_THREAD_GROUP | WINED3DSSF_GROUP_SHARED_MEMORY); + } + + if (sync_flags & WINED3DSSF_GROUP_SHARED_MEMORY) + { + shader_addline(buffer, "memoryBarrierShared();\n"); + sync_flags &= ~WINED3DSSF_GROUP_SHARED_MEMORY; + } + + if (sync_flags) + FIXME("Unhandled sync flags %#x.\n", sync_flags); +} + +static const struct wined3d_shader_resource_info *shader_glsl_get_resource_info( + const struct wined3d_shader_instruction *ins, const struct wined3d_shader_register *reg) +{ + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + unsigned int idx = reg->idx[0].offset; + + if (reg->type == WINED3DSPR_RESOURCE) + { + if (idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", idx); + return NULL; + } + return ®_maps->resource_info[idx]; + } + + if (reg->type == WINED3DSPR_UAV) + { + if (idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV index %u.\n", idx); + return NULL; + } + return ®_maps->uav_resource_info[idx]; + } + + FIXME("Unhandled register type %#x.\n", reg->type); + return NULL; +} + +static void shader_glsl_bufinfo(const struct wined3d_shader_instruction *ins) +{ + const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type); + const struct wined3d_shader_resource_info *resource_info; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + unsigned int resource_idx; + char dst_swizzle[6]; + DWORD write_mask; + + write_mask = shader_glsl_append_dst(buffer, ins); + shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle); + + if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[0].reg))) + return; + resource_idx = ins->src[0].reg.idx[0].offset; + + shader_addline(buffer, "ivec2("); + if (ins->src[0].reg.type == WINED3DSPR_RESOURCE) + { + unsigned int bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, + resource_idx, WINED3D_SAMPLER_DEFAULT); + shader_addline(buffer, "textureSize(%s_sampler%u)", prefix, bind_idx); + } + else + { + shader_addline(buffer, "imageSize(%s_image%u)", prefix, resource_idx); + } + if (resource_info->stride) + shader_addline(buffer, " / %u", resource_info->stride); + else if (resource_info->flags & WINED3D_VIEW_BUFFER_RAW) + shader_addline(buffer, " * 4"); + shader_addline(buffer, ", %u)%s);\n", resource_info->stride, dst_swizzle); +} + static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) { - static const unsigned int texture_size_component_count[] = - { - 0, /* WINED3D_SHADER_RESOURCE_NONE */ - 1, /* WINED3D_SHADER_RESOURCE_BUFFER */ - 1, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ - 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ - 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ - 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ - 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ - 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ - 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ - 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ - }; - const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; enum wined3d_shader_resource_type resource_type; - unsigned int resource_idx, sampler_bind_idx, i; + enum wined3d_shader_register_type reg_type; + unsigned int resource_idx, bind_idx, i; enum wined3d_data_type dst_data_type; struct glsl_src_param lod_param; char dst_swizzle[6]; @@ -4354,13 +5705,22 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], dst_data_type); shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle); + reg_type = ins->src[1].reg.type; resource_idx = ins->src[1].reg.idx[0].offset; - resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &lod_param); - sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, - resource_idx, WINED3D_SAMPLER_DEFAULT); + if (reg_type == WINED3DSPR_RESOURCE) + { + resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type; + bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, + resource_idx, WINED3D_SAMPLER_DEFAULT); + } + else + { + resource_type = ins->ctx->reg_maps->uav_resource_info[resource_idx].type; + bind_idx = resource_idx; + } - if (resource_type >= ARRAY_SIZE(texture_size_component_count)) + if (resource_type >= ARRAY_SIZE(resource_type_info)) { ERR("Unexpected resource type %#x.\n", resource_type); resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; @@ -4371,20 +5731,34 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) else shader_addline(ins->ctx->buffer, "vec4("); - shader_addline(ins->ctx->buffer, "textureSize(%s_sampler%u, %s), ", - shader_glsl_get_prefix(version->type), sampler_bind_idx, lod_param.param_str); - - for (i = 0; i < 3 - texture_size_component_count[resource_type]; ++i) - shader_addline(ins->ctx->buffer, "0, "); - - if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + if (reg_type == WINED3DSPR_RESOURCE) { - shader_addline(ins->ctx->buffer, "textureQueryLevels(%s_sampler%u)", - shader_glsl_get_prefix(version->type), sampler_bind_idx); + shader_addline(ins->ctx->buffer, "textureSize(%s_sampler%u, %s), ", + shader_glsl_get_prefix(version->type), bind_idx, lod_param.param_str); + + for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i) + shader_addline(ins->ctx->buffer, "0, "); + + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + { + shader_addline(ins->ctx->buffer, "textureQueryLevels(%s_sampler%u)", + shader_glsl_get_prefix(version->type), bind_idx); + } + else + { + FIXME("textureQueryLevels is not supported, returning 1 mipmap level.\n"); + shader_addline(ins->ctx->buffer, "1"); + } } else { - FIXME("textureQueryLevels is not supported, returning 1 mipmap level.\n"); + shader_addline(ins->ctx->buffer, "imageSize(%s_image%u), ", + shader_glsl_get_prefix(version->type), bind_idx); + + for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i) + shader_addline(ins->ctx->buffer, "0, "); + + /* For UAVs the returned miplevel count is always 1. */ shader_addline(ins->ctx->buffer, "1"); } @@ -4394,18 +5768,33 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) /* FIXME: The current implementation does not handle multisample textures correctly. */ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + unsigned int resource_idx, sampler_idx, sampler_bind_idx; struct glsl_src_param coord_param, lod_param; struct glsl_sample_function sample_function; - unsigned int sampler_bind_idx; + DWORD flags = WINED3D_GLSL_SAMPLE_LOAD; + BOOL has_lod_param; - shader_glsl_get_sample_function(ins->ctx, ins->src[1].reg.idx[0].offset, WINED3D_GLSL_SAMPLE_LOAD, - &sample_function); + if (wined3d_shader_instruction_has_texel_offset(ins)) + flags |= WINED3D_GLSL_SAMPLE_OFFSET; + + resource_idx = ins->src[1].reg.idx[0].offset; + sampler_idx = WINED3D_SAMPLER_DEFAULT; + + if (resource_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", resource_idx); + return; + } + has_lod_param = reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_BUFFER; + + shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param); - sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, - ins->src[1].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT); + sampler_bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, sampler_idx); shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, - NULL, NULL, lod_param.param_str, "%s", coord_param.param_str); + NULL, NULL, has_lod_param ? lod_param.param_str : NULL, &ins->texel_offset, + "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4421,11 +5810,13 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) flags |= WINED3D_GLSL_SAMPLE_GRAD; if (ins->handler_idx == WINED3DSIH_SAMPLE_LOD) flags |= WINED3D_GLSL_SAMPLE_LOD; + if (wined3d_shader_instruction_has_texel_offset(ins)) + flags |= WINED3D_GLSL_SAMPLE_OFFSET; resource_idx = ins->src[1].reg.idx[0].offset; sampler_idx = ins->src[2].reg.idx[0].offset; - shader_glsl_get_sample_function(ins->ctx, resource_idx, flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); switch (ins->handler_idx) @@ -4437,8 +5828,8 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) lod_param_str = lod_param.param_str; break; case WINED3DSIH_SAMPLE_GRAD: - shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dx_param); - shader_glsl_add_src_param(ins, &ins->src[4], sample_function.coord_mask, &dy_param); + shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dx_param); + shader_glsl_add_src_param(ins, &ins->src[4], sample_function.deriv_mask, &dy_param); dx_param_str = dx_param.param_str; dy_param_str = dy_param.param_str; break; @@ -4453,10 +5844,111 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx); shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, - dx_param_str, dy_param_str, lod_param_str, "%s", coord_param.param_str); + dx_param_str, dy_param_str, lod_param_str, &ins->texel_offset, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } +static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins) +{ + unsigned int resource_idx, sampler_idx, sampler_bind_idx; + struct glsl_src_param coord_param, compare_param; + struct glsl_sample_function sample_function; + const char *lod_param = NULL; + unsigned int coord_size; + DWORD flags = 0; + + if (ins->handler_idx == WINED3DSIH_SAMPLE_C_LZ) + { + lod_param = "0"; + flags |= WINED3D_GLSL_SAMPLE_LOD; + } + + if (wined3d_shader_instruction_has_texel_offset(ins)) + flags |= WINED3D_GLSL_SAMPLE_OFFSET; + + resource_idx = ins->src[1].reg.idx[0].offset; + sampler_idx = ins->src[2].reg.idx[0].offset; + + shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function); + coord_size = shader_glsl_get_write_mask_size(sample_function.coord_mask); + shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask >> 1, &coord_param); + shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &compare_param); + sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx); + shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, WINED3DSP_NOSWIZZLE, + NULL, NULL, lod_param, &ins->texel_offset, "vec%u(%s, %s)", + coord_size, coord_param.param_str, compare_param.param_str); + shader_glsl_release_sample_function(ins->ctx, &sample_function); +} + +static void shader_glsl_gather4(const struct wined3d_shader_instruction *ins) +{ + unsigned int resource_param_idx, resource_idx, sampler_idx, sampler_bind_idx, component_idx; + const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps; + const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); + struct glsl_src_param coord_param, compare_param, offset_param; + const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; + const struct wined3d_shader_resource_info *resource_info; + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + unsigned int coord_size, offset_size; + char dst_swizzle[6]; + BOOL has_offset; + + if (!gl_info->supported[ARB_TEXTURE_GATHER]) + { + FIXME("OpenGL implementation does not support textureGather.\n"); + return; + } + + has_offset = ins->handler_idx == WINED3DSIH_GATHER4_PO + || ins->handler_idx == WINED3DSIH_GATHER4_PO_C + || wined3d_shader_instruction_has_texel_offset(ins); + + resource_param_idx = + (ins->handler_idx == WINED3DSIH_GATHER4_PO || ins->handler_idx == WINED3DSIH_GATHER4_PO_C) ? 2 : 1; + resource_idx = ins->src[resource_param_idx].reg.idx[0].offset; + sampler_idx = ins->src[resource_param_idx + 1].reg.idx[0].offset; + component_idx = shader_glsl_swizzle_get_component(ins->src[resource_param_idx + 1].swizzle, 0); + sampler_bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, sampler_idx); + + if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[resource_param_idx].reg))) + return; + + if (resource_info->type >= ARRAY_SIZE(resource_type_info)) + { + ERR("Unexpected resource type %#x.\n", resource_info->type); + return; + } + shader_glsl_get_coord_size(resource_info->type, &coord_size, &offset_size); + + shader_glsl_swizzle_to_str(ins->src[resource_param_idx].swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], resource_info->data_type); + + shader_glsl_add_src_param(ins, &ins->src[0], (1u << coord_size) - 1, &coord_param); + + shader_addline(buffer, "textureGather%s(%s_sampler%u, %s", + has_offset ? "Offset" : "", prefix, sampler_bind_idx, coord_param.param_str); + if (ins->handler_idx == WINED3DSIH_GATHER4_C || ins->handler_idx == WINED3DSIH_GATHER4_PO_C) + { + shader_glsl_add_src_param(ins, &ins->src[resource_param_idx + 2], WINED3DSP_WRITEMASK_0, &compare_param); + shader_addline(buffer, ", %s", compare_param.param_str); + } + if (ins->handler_idx == WINED3DSIH_GATHER4_PO || ins->handler_idx == WINED3DSIH_GATHER4_PO_C) + { + shader_glsl_add_src_param(ins, &ins->src[1], (1u << offset_size) - 1, &offset_param); + shader_addline(buffer, ", %s", offset_param.param_str); + } + else if (has_offset) + { + int offset_immdata[4] = {ins->texel_offset.u, ins->texel_offset.v, ins->texel_offset.w}; + shader_addline(buffer, ", "); + shader_glsl_append_imm_ivec(buffer, offset_immdata, offset_size); + } + if (component_idx) + shader_addline(buffer, ", %u", component_idx); + + shader_addline(buffer, ")%s);\n", dst_swizzle); +} + static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins) { /* FIXME: Make this work for more than just 2D textures */ @@ -4517,24 +6009,24 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) * * It is a dependent read - not valid with conditional NP2 textures */ - shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask); switch(mask_size) { case 1: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str); + NULL, "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str); break; case 2: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str); + NULL, "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str); break; case 3: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str); + NULL, "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str); break; default: @@ -4639,10 +6131,10 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); - shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ - shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy"); + shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xy"); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4660,10 +6152,10 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins) shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ - shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); + shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xyz"); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4710,12 +6202,12 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function); shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask); /* Sample the texture */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, - NULL, NULL, NULL, "tmp0%s", coord_mask); + NULL, NULL, NULL, NULL, "tmp0%s", coord_mask); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4744,12 +6236,12 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n"); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function); shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, - NULL, NULL, NULL, "tmp0%s", coord_mask); + NULL, NULL, NULL, NULL, "tmp0%s", coord_mask); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4774,7 +6266,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) & WINED3D_PSARGS_TEXTRANSFORM_MASK; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); mask = sample_function.coord_mask; shader_glsl_write_mask_to_str(mask, coord_mask); @@ -4807,7 +6299,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "T%u%s + vec4(bumpenv_mat%u * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask); @@ -4849,8 +6341,8 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s.wx", src0_param.reg_name); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4865,8 +6357,8 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s.yz", src0_param.reg_name); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4880,10 +6372,10 @@ static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins) struct glsl_src_param src0_param; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s", src0_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4897,7 +6389,7 @@ static void shader_glsl_texkill(const struct wined3d_shader_instruction *ins) struct glsl_src_param src_param; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param); - shader_addline(ins->ctx->buffer, "if (bool(floatBitsToUint(%s))) discard;\n", src_param.param_str); + shader_addline(ins->ctx->buffer, "if (bool(%s)) discard;\n", src_param.param_str); } else { @@ -4968,15 +6460,37 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w if (args->vp_mode == vertexshader) { - if (input->sysval_semantic == WINED3D_SV_POSITION) + if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx) + { shader_addline(buffer, "ps_in[%u]%s = vpos%s;\n", shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask); + } else if (args->pointsprite && shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) + { shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", input->register_idx); + } + else if (input->sysval_semantic == WINED3D_SV_IS_FRONT_FACE) + { + shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n", + input->register_idx, reg_mask); + } + else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx) + { + if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) + shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_Layer);\n", + input->register_idx, reg_mask); + else + FIXME("ARB_fragment_layer_viewport is not supported.\n"); + } else - shader_addline(buffer, "ps_in[%u]%s = ps_link[%u]%s;\n", + { + if (input->sysval_semantic) + FIXME("Unhandled sysval semantic %#x.\n", input->sysval_semantic); + shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n", shader->u.ps.input_reg_map[input->register_idx], reg_mask, + shader_glsl_shader_input_name(gl_info), shader->u.ps.input_reg_map[input->register_idx], reg_mask); + } } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) { @@ -4986,7 +6500,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx)) shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n", shader->u.ps.input_reg_map[input->register_idx], reg_mask, - gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + needs_legacy_glsl_syntax(gl_info) ? "gl_TexCoord" : "ffp_varying_texcoord", semantic_idx, reg_mask); else shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", @@ -5012,17 +6526,16 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w } } -/********************************************* - * Vertex Shader Specific Code begins here - ********************************************/ - static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry) { struct glsl_program_key key; key.vs_id = entry->vs.id; + key.hs_id = entry->hs.id; + key.ds_id = entry->ds.id; key.gs_id = entry->gs.id; key.ps_id = entry->ps.id; + key.cs_id = entry->cs.id; if (wine_rb_put(&priv->program_lookup, &key, &entry->program_lookup_entry) == -1) { @@ -5031,16 +6544,11 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh } static struct glsl_shader_prog_link *get_glsl_program_entry(const struct shader_glsl_priv *priv, - GLuint vs_id, GLuint gs_id, GLuint ps_id) + const struct glsl_program_key *key) { struct wine_rb_entry *entry; - struct glsl_program_key key; - key.vs_id = vs_id; - key.gs_id = gs_id; - key.ps_id = ps_id; - - entry = wine_rb_get(&priv->program_lookup, &key); + entry = wine_rb_get(&priv->program_lookup, key); return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL; } @@ -5053,33 +6561,36 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc GL_EXTCALL(glDeleteProgram(entry->id)); if (entry->vs.id) list_remove(&entry->vs.shader_entry); + if (entry->hs.id) + list_remove(&entry->hs.shader_entry); + if (entry->ds.id) + list_remove(&entry->ds.shader_entry); if (entry->gs.id) list_remove(&entry->gs.shader_entry); if (entry->ps.id) list_remove(&entry->ps.shader_entry); - HeapFree(GetProcessHeap(), 0, entry->vs.uniform_f_locations); - HeapFree(GetProcessHeap(), 0, entry->ps.uniform_f_locations); + if (entry->cs.id) + list_remove(&entry->cs.shader_entry); HeapFree(GetProcessHeap(), 0, entry); } -static void handle_ps3_input(struct shader_glsl_priv *priv, +static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info, const DWORD *map, const struct wined3d_shader_signature *input_signature, const struct wined3d_shader_reg_maps *reg_maps_in, const struct wined3d_shader_signature *output_signature, const struct wined3d_shader_reg_maps *reg_maps_out) { - struct wined3d_string_buffer *buffer = &priv->shader_buffer; - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; - unsigned int i, j; - DWORD *set; - DWORD in_idx; - unsigned int in_count = vec4_varyings(3, gl_info); - unsigned int max_varyings = legacy_context ? in_count + 2 : in_count; - char reg_mask[6]; struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers); + const char *out_array_name = shader_glsl_shader_output_name(gl_info); + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + unsigned int in_count = vec4_varyings(3, gl_info); + unsigned int max_varyings = needs_legacy_glsl_syntax(gl_info) ? in_count + 2 : in_count; + DWORD in_idx, *set = NULL; + unsigned int i, j; + char reg_mask[6]; - set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * max_varyings); + set = wined3d_calloc(max_varyings, sizeof(*set)); for (i = 0; i < input_signature->element_count; ++i) { @@ -5103,7 +6614,7 @@ static void handle_ps3_input(struct shader_glsl_priv *priv, else if (in_idx == in_count + 1) string_buffer_sprintf(destination, "gl_FrontSecondaryColor"); else - string_buffer_sprintf(destination, "ps_link[%u]", in_idx); + string_buffer_sprintf(destination, "%s[%u]", out_array_name, in_idx); if (!set[in_idx]) set[in_idx] = ~0u; @@ -5124,7 +6635,7 @@ static void handle_ps3_input(struct shader_glsl_priv *priv, set[in_idx] |= mask & reg_maps_out->u.output_registers_mask[output->register_idx]; shader_glsl_write_mask_to_str(mask, reg_mask); - shader_addline(buffer, "%s%s = vs_out[%u]%s;\n", + shader_addline(buffer, "%s%s = outputs[%u]%s;\n", destination->buffer, reg_mask, output->register_idx, reg_mask); } } @@ -5136,13 +6647,18 @@ static void handle_ps3_input(struct shader_glsl_priv *priv, if (!set[i] || set[i] == WINED3DSP_WRITEMASK_ALL) continue; - if (set[i] == ~0U) set[i] = 0; + if (set[i] == ~0u) + set[i] = 0; size = 0; - if (!(set[i] & WINED3DSP_WRITEMASK_0)) reg_mask[size++] = 'x'; - if (!(set[i] & WINED3DSP_WRITEMASK_1)) reg_mask[size++] = 'y'; - if (!(set[i] & WINED3DSP_WRITEMASK_2)) reg_mask[size++] = 'z'; - if (!(set[i] & WINED3DSP_WRITEMASK_3)) reg_mask[size++] = 'w'; + if (!(set[i] & WINED3DSP_WRITEMASK_0)) + reg_mask[size++] = 'x'; + if (!(set[i] & WINED3DSP_WRITEMASK_1)) + reg_mask[size++] = 'y'; + if (!(set[i] & WINED3DSP_WRITEMASK_2)) + reg_mask[size++] = 'z'; + if (!(set[i] & WINED3DSP_WRITEMASK_3)) + reg_mask[size++] = 'w'; reg_mask[size] = '\0'; if (i == in_count) @@ -5150,33 +6666,120 @@ static void handle_ps3_input(struct shader_glsl_priv *priv, else if (i == in_count + 1) string_buffer_sprintf(destination, "gl_FrontSecondaryColor"); else - string_buffer_sprintf(destination, "ps_link[%u]", i); + string_buffer_sprintf(destination, "%s[%u]", out_array_name, i); - if (size == 1) shader_addline(buffer, "%s.%s = 0.0;\n", destination->buffer, reg_mask); - else shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination->buffer, reg_mask, size); + if (size == 1) + shader_addline(buffer, "%s.%s = 0.0;\n", destination->buffer, reg_mask); + else + shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination->buffer, reg_mask, size); } HeapFree(GetProcessHeap(), 0, set); string_buffer_release(&priv->string_buffers, destination); } -/* Context activation is done by the caller. */ -static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, - const struct wined3d_shader *vs, const struct wined3d_shader *ps, - BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info) +static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv, + unsigned int input_count, const struct wined3d_shader_signature *output_signature, + const struct wined3d_shader_reg_maps *reg_maps_out, const char *output_variable_name) { struct wined3d_string_buffer *buffer = &priv->shader_buffer; - GLuint ret; - DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0; + char reg_mask[6]; unsigned int i; + + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *output = &output_signature->elements[i]; + + if (!(reg_maps_out->output_registers & (1u << output->register_idx))) + continue; + + if (output->stream_idx) + continue; + + if (output->register_idx >= input_count) + continue; + + shader_glsl_write_mask_to_str(output->mask, reg_mask); + + shader_addline(buffer, "%s.reg[%u]%s = outputs[%u]%s;\n", + output_variable_name, output->register_idx, reg_mask, output->register_idx, reg_mask); + } +} + +static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv, + const struct wined3d_gl_info *gl_info, const DWORD *map, + const struct wined3d_shader_signature *input_signature, + const struct wined3d_shader_reg_maps *reg_maps_in, unsigned int input_count, + const struct wined3d_shader_signature *output_signature, + const struct wined3d_shader_reg_maps *reg_maps_out, BOOL per_vertex_point_size) +{ + struct wined3d_string_buffer *buffer = &priv->shader_buffer; const char *semantic_name; UINT semantic_idx; char reg_mask[6]; - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + unsigned int i; + + /* First, sort out position and point size system values. */ + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *output = &output_signature->elements[i]; + + if (!(reg_maps_out->output_registers & (1u << output->register_idx))) + continue; + + if (output->stream_idx) + continue; + + semantic_name = output->semantic_name; + semantic_idx = output->semantic_idx; + shader_glsl_write_mask_to_str(output->mask, reg_mask); + + if (output->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx) + { + shader_addline(buffer, "gl_Position%s = outputs[%u]%s;\n", + reg_mask, output->register_idx, reg_mask); + } + else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size) + { + shader_addline(buffer, "gl_PointSize = clamp(outputs[%u].%c, " + "ffp_point.size_min, ffp_point.size_max);\n", output->register_idx, reg_mask[1]); + } + else if (output->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx) + { + shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n", + output->register_idx, reg_mask); + } + else if (output->sysval_semantic) + { + FIXME("Unhandled sysval semantic %#x.\n", output->sysval_semantic); + } + } + + /* Then, setup the pixel shader input. */ + if (reg_maps_out->shader_version.major < 4) + shader_glsl_setup_vs3_output(priv, gl_info, map, input_signature, reg_maps_in, + output_signature, reg_maps_out); + else + shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature, reg_maps_out, "shader_out"); +} + +/* Context activation is done by the caller. */ +static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl_priv *priv, + const struct wined3d_shader *vs, const struct wined3d_shader *ps, + BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info) +{ + const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); + DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + const char *semantic_name; + UINT semantic_idx; + char reg_mask[6]; + unsigned int i; + GLuint ret; string_buffer_clear(buffer); - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, &vs->reg_maps.shader_version)); + shader_glsl_add_version_declaration(buffer, gl_info); if (per_vertex_point_size) { @@ -5191,7 +6794,7 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, DWORD colors_written_mask[2] = {0}; DWORD texcoords_written_mask[MAX_TEXTURES] = {0}; - if (!legacy_context) + if (!legacy_syntax) { declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_specular;\n"); @@ -5199,7 +6802,7 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); } - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output); + shader_addline(buffer, "void setup_vs_output(in vec4 outputs[%u])\n{\n", vs->limits->packed_output); for (i = 0; i < vs->output_signature.element_count; ++i) { @@ -5216,39 +6819,39 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR) && semantic_idx < 2) { - if (legacy_context) - shader_addline(buffer, "gl_Front%sColor%s = vs_out[%u]%s;\n", + if (legacy_syntax) + shader_addline(buffer, "gl_Front%sColor%s = outputs[%u]%s;\n", semantic_idx ? "Secondary" : "", reg_mask, output->register_idx, reg_mask); else - shader_addline(buffer, "ffp_varying_%s%s = clamp(vs_out[%u]%s, 0.0, 1.0);\n", + shader_addline(buffer, "ffp_varying_%s%s = clamp(outputs[%u]%s, 0.0, 1.0);\n", semantic_idx ? "specular" : "diffuse", reg_mask, output->register_idx, reg_mask); colors_written_mask[semantic_idx] = write_mask; } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx) { - shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", + shader_addline(buffer, "gl_Position%s = outputs[%u]%s;\n", reg_mask, output->register_idx, reg_mask); } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD)) { if (semantic_idx < MAX_TEXTURES) { - shader_addline(buffer, "%s[%u]%s = vs_out[%u]%s;\n", - legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", + shader_addline(buffer, "%s[%u]%s = outputs[%u]%s;\n", + legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", semantic_idx, reg_mask, output->register_idx, reg_mask); texcoords_written_mask[semantic_idx] = write_mask; } } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size) { - shader_addline(buffer, "gl_PointSize = clamp(vs_out[%u].%c, ffp_point.size_min, ffp_point.size_max);\n", - output->register_idx, reg_mask[1]); + shader_addline(buffer, "gl_PointSize = clamp(outputs[%u].%c, " + "ffp_point.size_min, ffp_point.size_max);\n", output->register_idx, reg_mask[1]); } else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG)) { - shader_addline(buffer, "%s = clamp(vs_out[%u].%c, 0.0, 1.0);\n", - legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord", + shader_addline(buffer, "%s = clamp(outputs[%u].%c, 0.0, 1.0);\n", + legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord", output->register_idx, reg_mask[1]); } } @@ -5260,11 +6863,11 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, shader_glsl_write_mask_to_str(~colors_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask); if (!i) shader_addline(buffer, "%s%s = vec4(1.0)%s;\n", - legacy_context ? "gl_FrontColor" : "ffp_varying_diffuse", + legacy_syntax ? "gl_FrontColor" : "ffp_varying_diffuse", reg_mask, reg_mask); else shader_addline(buffer, "%s%s = vec4(0.0)%s;\n", - legacy_context ? "gl_FrontSecondaryColor" : "ffp_varying_specular", + legacy_syntax ? "gl_FrontSecondaryColor" : "ffp_varying_specular", reg_mask, reg_mask); } } @@ -5281,44 +6884,18 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, shader_glsl_write_mask_to_str(~texcoords_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask); shader_addline(buffer, "%s[%u]%s = vec4(0.0)%s;\n", - legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", i, reg_mask, reg_mask); + legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", i, reg_mask, reg_mask); } } } else { - UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input); + unsigned int in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input); - declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", in_count); - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output); - - /* First, sort out position and point size. Those are not passed to the pixel shader */ - for (i = 0; i < vs->output_signature.element_count; ++i) - { - const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i]; - - if (!(vs->reg_maps.output_registers & (1u << output->register_idx))) - continue; - - semantic_name = output->semantic_name; - semantic_idx = output->semantic_idx; - shader_glsl_write_mask_to_str(output->mask, reg_mask); - - if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx) - { - shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n", - reg_mask, output->register_idx, reg_mask); - } - else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size) - { - shader_addline(buffer, "gl_PointSize = clamp(vs_out[%u].%c, ffp_point.size_min, ffp_point.size_max);\n", - output->register_idx, reg_mask[1]); - } - } - - /* Then, fix the pixel shader input */ - handle_ps3_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature, - &ps->reg_maps, &vs->output_signature, &vs->reg_maps); + shader_glsl_declare_shader_outputs(gl_info, buffer, in_count); + shader_addline(buffer, "void setup_vs_output(in vec4 outputs[%u])\n{\n", vs->limits->packed_output); + shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature, + &ps->reg_maps, 0, &vs->output_signature, &vs->reg_maps, per_vertex_point_size); } shader_addline(buffer, "}\n"); @@ -5330,18 +6907,123 @@ static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv, return ret; } -static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer) +static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv, + const struct wined3d_shader *shader, unsigned int input_count, + const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup) { - shader_addline(buffer, "tmp0.xyz = pow(gl_FragData[0].xyz, vec3(srgb_const0.x));\n"); - shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n"); - shader_addline(buffer, "tmp1.xyz = gl_FragData[0].xyz * vec3(srgb_const0.w);\n"); - shader_addline(buffer, "bvec3 srgb_compare = lessThan(gl_FragData[0].xyz, vec3(srgb_const1.x));\n"); - shader_addline(buffer, "gl_FragData[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n"); - shader_addline(buffer, "gl_FragData[0] = clamp(gl_FragData[0], 0.0, 1.0);\n"); + const char *prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type); + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + + if (rasterizer_setup) + input_count = min(vec4_varyings(4, gl_info), input_count); + + if (input_count) + shader_glsl_declare_shader_outputs(gl_info, buffer, input_count); + + shader_addline(buffer, "void setup_%s_output(in vec4 outputs[%u])\n{\n", + prefix, shader->limits->packed_output); + + if (rasterizer_setup) + shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, NULL, NULL, + NULL, input_count, &shader->output_signature, &shader->reg_maps, FALSE); + else + shader_glsl_setup_sm4_shader_output(priv, input_count, &shader->output_signature, + &shader->reg_maps, "shader_out"); + + shader_addline(buffer, "}\n"); } -static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, enum wined3d_ffp_ps_fog_mode mode) +static void shader_glsl_generate_patch_constant_name(struct wined3d_string_buffer *buffer, + const struct wined3d_shader_signature_element *constant, unsigned int *user_constant_idx, + const char *reg_mask) { + if (!constant->sysval_semantic) + { + shader_addline(buffer, "user_patch_constant[%u]%s", (*user_constant_idx)++, reg_mask); + return; + } + + switch (constant->sysval_semantic) + { + case WINED3D_SV_TESS_FACTOR_QUADEDGE: + case WINED3D_SV_TESS_FACTOR_TRIEDGE: + case WINED3D_SV_TESS_FACTOR_LINEDET: + case WINED3D_SV_TESS_FACTOR_LINEDEN: + shader_addline(buffer, "gl_TessLevelOuter[%u]", constant->semantic_idx); + break; + case WINED3D_SV_TESS_FACTOR_QUADINT: + case WINED3D_SV_TESS_FACTOR_TRIINT: + shader_addline(buffer, "gl_TessLevelInner[%u]", constant->semantic_idx); + break; + default: + FIXME("Unhandled sysval semantic %#x.\n", constant->sysval_semantic); + shader_addline(buffer, "vec4(0.0)%s", reg_mask); + } +} + +static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buffer *buffer, + const struct wined3d_shader_signature *signature, BOOL input_setup) +{ + unsigned int i, register_count, user_constant_index, user_constant_count; + + register_count = user_constant_count = 0; + for (i = 0; i < signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *constant = &signature->elements[i]; + register_count = max(constant->register_idx + 1, register_count); + if (!constant->sysval_semantic) + ++user_constant_count; + } + + if (user_constant_count) + shader_addline(buffer, "patch %s vec4 user_patch_constant[%u];\n", + input_setup ? "in" : "out", user_constant_count); + if (input_setup) + shader_addline(buffer, "vec4 vpc[%u];\n", register_count); + + shader_addline(buffer, "void setup_patch_constant_%s()\n{\n", input_setup ? "input" : "output"); + for (i = 0, user_constant_index = 0; i < signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *constant = &signature->elements[i]; + char reg_mask[6]; + + shader_glsl_write_mask_to_str(constant->mask, reg_mask); + + if (input_setup) + shader_addline(buffer, "vpc[%u]%s", constant->register_idx, reg_mask); + else + shader_glsl_generate_patch_constant_name(buffer, constant, &user_constant_index, reg_mask); + + shader_addline(buffer, " = "); + + if (input_setup) + shader_glsl_generate_patch_constant_name(buffer, constant, &user_constant_index, reg_mask); + else + shader_addline(buffer, "hs_out[%u]%s", constant->register_idx, reg_mask); + + shader_addline(buffer, ";\n"); + } + shader_addline(buffer, "}\n"); +} + +static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info) +{ + const char *output = get_fragment_output(gl_info); + + shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n", output); + shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n"); + shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n", output); + shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz, vec3(srgb_const1.x));\n", output); + shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); + shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output, output); +} + +static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode) +{ + const char *output = get_fragment_output(gl_info); + switch (mode) { case WINED3D_FFP_PS_FOG_OFF: @@ -5365,8 +7047,87 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, return; } - shader_addline(buffer, "gl_FragData[0].xyz = mix(ffp_fog.color.xyz, gl_FragData[0].xyz," - " clamp(fog, 0.0, 1.0));\n"); + shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog, 0.0, 1.0));\n", + output, output); +} + +static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func) +{ + /* alpha_func is the PASS condition, not the DISCARD condition. Instead of + * flipping all the operators here, just negate the comparison below. */ + static const char * const comparison_operator[] = + { + "", /* WINED3D_CMP_NEVER */ + "<", /* WINED3D_CMP_LESS */ + "==", /* WINED3D_CMP_EQUAL */ + "<=", /* WINED3D_CMP_LESSEQUAL */ + ">", /* WINED3D_CMP_GREATER */ + "!=", /* WINED3D_CMP_NOTEQUAL */ + ">=", /* WINED3D_CMP_GREATEREQUAL */ + "" /* WINED3D_CMP_ALWAYS */ + }; + + if (alpha_func == WINED3D_CMP_ALWAYS) + return; + + if (alpha_func != WINED3D_CMP_NEVER) + shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n", + get_fragment_output(gl_info), comparison_operator[alpha_func - WINED3D_CMP_NEVER]); + shader_addline(buffer, " discard;\n"); +} + +static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, + const struct wined3d_gl_info *gl_info) +{ + if (gl_info->supported[ARB_GPU_SHADER5]) + shader_addline(buffer, "#extension GL_ARB_gpu_shader5 : enable\n"); + if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS]) + shader_addline(buffer, "#extension GL_ARB_shader_atomic_counters : enable\n"); + if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) + shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); + if (gl_info->supported[ARB_SHADER_IMAGE_LOAD_STORE]) + shader_addline(buffer, "#extension GL_ARB_shader_image_load_store : enable\n"); + if (gl_info->supported[ARB_SHADER_IMAGE_SIZE]) + shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n"); + if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT]) + shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n"); + if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) + shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n"); + if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]) + shader_addline(buffer, "#extension GL_ARB_shading_language_packing : enable\n"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY]) + shader_addline(buffer, "#extension GL_ARB_texture_cube_map_array : enable\n"); + if (gl_info->supported[ARB_TEXTURE_GATHER]) + shader_addline(buffer, "#extension GL_ARB_texture_gather : enable\n"); + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); + if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) + shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); + if (gl_info->supported[EXT_GPU_SHADER4]) + shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); + if (gl_info->supported[EXT_TEXTURE_ARRAY]) + shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n"); +} + +static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info, + struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, + const struct ps_compile_args *args) +{ + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + + /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */ + if (reg_maps->shader_version.major < 2) + shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info)); + + if (args->srgb_correction) + shader_glsl_generate_srgb_write_correction(buffer, gl_info); + + /* SM < 3 does not replace the fog stage. */ + if (reg_maps->shader_version.major < 3) + shader_glsl_generate_fog_code(buffer, gl_info, args->fog); + + shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1); } /* Context activation is done by the caller. */ @@ -5376,45 +7137,210 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; + const char *prefix = shader_glsl_get_prefix(version->type); const struct wined3d_gl_info *gl_info = context->gl_info; - const DWORD *function = shader->function; + const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); + unsigned int i, extra_constants_needed = 0; struct shader_glsl_ctx_priv priv_ctx; - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; - - /* Create the hw GLSL shader object and assign it as the shader->prgId */ - GLuint shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); + GLuint shader_id; + DWORD map; memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.cur_ps_args = args; priv_ctx.cur_np2fixup_info = np2fixup_info; priv_ctx.string_buffers = string_buffers; - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, ®_maps->shader_version)); + shader_glsl_add_version_declaration(buffer, gl_info); - if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) - shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); + shader_glsl_enable_extensions(buffer, gl_info); + if (gl_info->supported[ARB_DERIVATIVE_CONTROL]) + shader_addline(buffer, "#extension GL_ARB_derivative_control : enable\n"); + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n"); + if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT]) + shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n"); if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n"); - if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) - shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); /* The spec says that it doesn't have to be explicitly enabled, but the * nvidia drivers write a warning if we don't do so. */ if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n"); - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); - if (gl_info->supported[EXT_GPU_SHADER4]) - shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); /* Base Declarations */ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + /* Declare uniforms for NP2 texcoord fixup: + * This is NOT done inside the loop that declares the texture samplers + * since the NP2 fixup code is currently only used for the GeforceFX + * series and when forcing the ARB_npot extension off. Modern cards just + * skip the code anyway, so put it inside a separate loop. */ + if (args->np2_fixup) + { + struct ps_np2fixup_info *fixup = priv_ctx.cur_np2fixup_info; + unsigned int cur = 0; + + /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height] + * while D3D has them in the (normalized) [0,1]x[0,1] range. + * samplerNP2Fixup stores texture dimensions and is updated through + * shader_glsl_load_np2fixup_constants when the sampler changes. */ + + for (i = 0; i < shader->limits->sampler; ++i) + { + if (!reg_maps->resource_info[i].type || !(args->np2_fixup & (1u << i))) + continue; + + if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) + { + FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); + continue; + } + + fixup->idx[i] = cur++; + } + + fixup->num_consts = (cur + 1) >> 1; + fixup->active = args->np2_fixup; + shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts); + } + + if (version->major < 3 || args->vp_mode != vertexshader) + { + shader_addline(buffer, "uniform struct\n{\n"); + shader_addline(buffer, " vec4 color;\n"); + shader_addline(buffer, " float density;\n"); + shader_addline(buffer, " float end;\n"); + shader_addline(buffer, " float scale;\n"); + shader_addline(buffer, "} ffp_fog;\n"); + + if (needs_legacy_glsl_syntax(gl_info)) + { + if (glsl_is_color_reg_read(shader, 0)) + shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); + if (glsl_is_color_reg_read(shader, 1)) + shader_addline(buffer, "vec4 ffp_varying_specular;\n"); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "float ffp_varying_fogcoord;\n"); + } + else + { + if (glsl_is_color_reg_read(shader, 0)) + declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n"); + if (glsl_is_color_reg_read(shader, 1)) + declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n"); + declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES); + declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); + } + } + + if (version->major >= 3) + { + unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); + + if (args->vp_mode == vertexshader) + shader_glsl_declare_shader_inputs(gl_info, buffer, in_count); + shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); + } + + for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i) + { + if (!(map & 1)) + continue; + + shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", i); + + if (reg_maps->luminanceparams & (1u << i)) + { + shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", i); + shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", i); + extra_constants_needed++; + } + + extra_constants_needed++; + } + + if (args->srgb_correction) + { + shader_addline(buffer, "const vec4 srgb_const0 = "); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0); + shader_addline(buffer, ";\n"); + shader_addline(buffer, "const vec4 srgb_const1 = "); + shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1); + shader_addline(buffer, ";\n"); + } + if (reg_maps->vpos || reg_maps->usesdsy) + { + if (reg_maps->usesdsy || !gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + { + ++extra_constants_needed; + shader_addline(buffer, "uniform vec4 ycorrection;\n"); + } + if (reg_maps->vpos) + { + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + { + if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) + shader_addline(buffer, "layout(%spixel_center_integer) in vec4 gl_FragCoord;\n", + args->render_offscreen ? "" : "origin_upper_left, "); + else if (!args->render_offscreen) + shader_addline(buffer, "layout(origin_upper_left) in vec4 gl_FragCoord;\n"); + } + shader_addline(buffer, "vec4 vpos;\n"); + } + } + + if (args->alpha_test_func + 1 != WINED3D_CMP_ALWAYS) + shader_addline(buffer, "uniform float alpha_test_ref;\n"); + + if (!needs_legacy_glsl_syntax(gl_info)) + { + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = 0) "); + shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers); + } + + if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants) + FIXME("Insufficient uniforms to run this shader.\n"); + + shader_addline(buffer, "void main()\n{\n"); + + /* Direct3D applications expect integer vPos values, while OpenGL drivers + * add approximately 0.5. This causes off-by-one problems as spotted by + * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly + * 0.5, but rather something like 0.49999999 or 0.50000001, which still + * causes precision troubles when we just subtract 0.5. + * + * To deal with that, just floor() the position. This will eliminate the + * fraction on all cards. + * + * TODO: Test how this behaves with multisampling. + * + * An advantage of floor is that it works even if the driver doesn't add + * 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values + * to return in gl_FragCoord, even though coordinates specify the pixel + * centers instead of the pixel corners. This code will behave correctly + * on drivers that returns integer values. */ + if (reg_maps->vpos) + { + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + shader_addline(buffer, "vpos = gl_FragCoord;\n"); + else if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) + shader_addline(buffer, + "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n"); + else + shader_addline(buffer, + "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n"); + } + if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader) { unsigned int i; WORD map = reg_maps->texcoord; - if (legacy_context) + if (legacy_syntax) { if (glsl_is_color_reg_read(shader, 0)) shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n"); @@ -5430,14 +7356,14 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", i); else if (args->texcoords_initialized & (1u << i)) shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n", i, - legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", i); + legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", i); else shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", i); shader_addline(buffer, "vec4 T%u = ffp_texcoord[%u];\n", i, i); } } - if (legacy_context) + if (legacy_syntax) shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n"); } @@ -5446,113 +7372,380 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args, gl_info); /* Base Shader Body */ - shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; - /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */ - if (reg_maps->shader_version.major < 2) - { - /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */ - shader_addline(buffer, "gl_FragData[0] = R0;\n"); - } - - if (args->srgb_correction) - shader_glsl_generate_srgb_write_correction(buffer); - - /* SM < 3 does not replace the fog stage. */ - if (reg_maps->shader_version.major < 3) - shader_glsl_generate_fog_code(buffer, args->fog); + /* In SM4+ the shader epilogue is generated by the "ret" instruction. */ + if (reg_maps->shader_version.major < 4) + shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args); shader_addline(buffer, "}\n"); + shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); TRACE("Compiling shader object %u.\n", shader_id); shader_glsl_compile(gl_info, shader_id, buffer->buffer); return shader_id; } -/* Context activation is done by the caller. */ -static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context, - struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, - const struct wined3d_shader *shader, +static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_info, + struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct vs_compile_args *args) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - const struct wined3d_gl_info *gl_info = context->gl_info; - const DWORD *function = shader->function; - struct shader_glsl_ctx_priv priv_ctx; - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); + unsigned int i; - /* Create the hw GLSL shader program and assign it as the shader->prgId */ - GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); - - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, ®_maps->shader_version)); - - if (gl_info->supported[ARB_DRAW_INSTANCED]) - shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n"); - if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) - shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); - if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) - shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); - if (gl_info->supported[EXT_GPU_SHADER4]) - shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); - - memset(&priv_ctx, 0, sizeof(priv_ctx)); - priv_ctx.cur_vs_args = args; - priv_ctx.string_buffers = string_buffers; - - /* Base Declarations */ - shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); - - /* Base Shader Body */ - shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); - - /* Unpack outputs */ - shader_addline(buffer, "order_ps_input(vs_out);\n"); + /* Unpack outputs. */ + shader_addline(buffer, "setup_vs_output(vs_out);\n"); /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE), * the fog frag coord is thrown away. If the fog frag coord is used, but not written by - * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0) + * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0). */ if (reg_maps->shader_version.major < 3) { if (args->fog_src == VS_FOG_Z) shader_addline(buffer, "%s = gl_Position.z;\n", - legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord"); + legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord"); else if (!reg_maps->fog) shader_addline(buffer, "%s = 0.0;\n", - legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord"); + legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord"); } - /* We always store the clipplanes without y inversion */ + /* We always store the clipplanes without y inversion. */ if (args->clip_enabled) - shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); + { + if (legacy_syntax) + shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); + else + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + shader_addline(buffer, "gl_ClipDistance[%u] = dot(gl_Position, clip_planes[%u]);\n", i, i); + } if (args->point_size && !args->per_vertex_point_size) shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); - /* Write the final position. - * - * OpenGL coordinates specify the center of the pixel while d3d coords specify - * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains - * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x - * contains 1.0 to allow a mad. - */ - shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n"); - shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n"); + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) + shader_glsl_fixup_position(buffer); +} - /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c - * - * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run - * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w, - * which is the same as z = z * 2 - w. - */ - shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); +/* Context activation is done by the caller. */ +static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args) +{ + struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_shader_version *version = ®_maps->shader_version; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct shader_glsl_ctx_priv priv_ctx; + GLuint shader_id; + unsigned int i; + + memset(&priv_ctx, 0, sizeof(priv_ctx)); + priv_ctx.cur_vs_args = args; + priv_ctx.string_buffers = string_buffers; + + shader_glsl_add_version_declaration(buffer, gl_info); + + shader_glsl_enable_extensions(buffer, gl_info); + if (gl_info->supported[ARB_DRAW_INSTANCED]) + shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n"); + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); + + /* Base Declarations */ + shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + + for (i = 0; i < shader->input_signature.element_count; ++i) + shader_glsl_declare_generic_vertex_attribute(buffer, gl_info, &shader->input_signature.elements[i]); + + if (args->point_size && !args->per_vertex_point_size) + { + shader_addline(buffer, "uniform struct\n{\n"); + shader_addline(buffer, " float size;\n"); + shader_addline(buffer, " float size_min;\n"); + shader_addline(buffer, " float size_max;\n"); + shader_addline(buffer, "} ffp_point;\n"); + } + + if (!needs_legacy_glsl_syntax(gl_info)) + { + if (args->clip_enabled) + shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances); + + if (version->major < 3) + { + declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n"); + declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n"); + declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); + declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); + } + } + + if (version->major < 4) + shader_addline(buffer, "void setup_vs_output(in vec4[%u]);\n", shader->limits->packed_output); + + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); + + if (reg_maps->shader_version.major >= 4) + shader_glsl_generate_sm4_output_setup(priv, shader, args->next_shader_input_count, + gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL); + + shader_addline(buffer, "void main()\n{\n"); + + /* Base Shader Body */ + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; + + /* In SM4+ the shader epilogue is generated by the "ret" instruction. */ + if (reg_maps->shader_version.major < 4) + shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, args); shader_addline(buffer, "}\n"); + shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); + TRACE("Compiling shader object %u.\n", shader_id); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); + + return shader_id; +} + +static void shader_glsl_generate_default_control_point_phase(const struct wined3d_shader *shader, + struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps) +{ + const struct wined3d_shader_signature *output_signature = &shader->output_signature; + char reg_mask[6]; + unsigned int i; + + for (i = 0; i < output_signature->element_count; ++i) + { + const struct wined3d_shader_signature_element *output = &output_signature->elements[i]; + + shader_glsl_write_mask_to_str(output->mask, reg_mask); + shader_addline(buffer, "shader_out[gl_InvocationID].reg[%u]%s = shader_in[gl_InvocationID].reg[%u]%s;\n", + output->register_idx, reg_mask, output->register_idx, reg_mask); + } +} + +static HRESULT shader_glsl_generate_shader_phase(const struct wined3d_shader *shader, + struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps, + struct shader_glsl_ctx_priv *priv_ctx, const struct wined3d_shader_phase *phase, + const char *phase_name, unsigned phase_idx) +{ + unsigned int i; + HRESULT hr; + + shader_addline(buffer, "void hs_%s_phase%u(%s)\n{\n", + phase_name, phase_idx, phase->instance_count ? "int phase_instance_id" : ""); + for (i = 0; i < phase->temporary_count; ++i) + shader_addline(buffer, "vec4 R%u;\n", i); + hr = shader_generate_code(shader, buffer, reg_maps, priv_ctx, phase->start, phase->end); + shader_addline(buffer, "}\n"); + return hr; +} + +static void shader_glsl_generate_shader_phase_invocation(struct wined3d_string_buffer *buffer, + const struct wined3d_shader_phase *phase, const char *phase_name, unsigned int phase_idx) +{ + if (phase->instance_count) + { + shader_addline(buffer, "for (int i = 0; i < %u; ++i)\n{\n", phase->instance_count); + shader_addline(buffer, "hs_%s_phase%u(i);\n", phase_name, phase_idx); + shader_addline(buffer, "}\n"); + } + else + { + shader_addline(buffer, "hs_%s_phase%u();\n", phase_name, phase_idx); + } +} + +static GLuint shader_glsl_generate_hull_shader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, const struct wined3d_shader *shader) +{ + struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_hull_shader *hs = &shader->u.hs; + const struct wined3d_shader_phase *phase; + struct shader_glsl_ctx_priv priv_ctx; + GLuint shader_id; + unsigned int i; + + memset(&priv_ctx, 0, sizeof(priv_ctx)); + priv_ctx.string_buffers = string_buffers; + + shader_glsl_add_version_declaration(buffer, gl_info); + + shader_glsl_enable_extensions(buffer, gl_info); + shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n"); + + shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + + shader_addline(buffer, "layout(vertices = %u) out;\n", hs->output_vertex_count); + + shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input); + shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; } shader_out[];\n", shader->limits->packed_output); + + shader_glsl_generate_patch_constant_setup(buffer, &shader->patch_constant_signature, FALSE); + + if (hs->phases.control_point) + { + shader_addline(buffer, "void setup_hs_output(in vec4 outputs[%u])\n{\n", + shader->limits->packed_output); + shader_glsl_setup_sm4_shader_output(priv, shader->limits->packed_output, &shader->output_signature, + &shader->reg_maps, "shader_out[gl_InvocationID]"); + shader_addline(buffer, "}\n"); + } + + shader_addline(buffer, "void hs_control_point_phase()\n{\n"); + if ((phase = hs->phases.control_point)) + { + for (i = 0; i < phase->temporary_count; ++i) + shader_addline(buffer, "vec4 R%u;\n", i); + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, phase->start, phase->end))) + return 0; + shader_addline(buffer, "setup_hs_output(hs_out);\n"); + } + else + { + shader_glsl_generate_default_control_point_phase(shader, buffer, reg_maps); + } + shader_addline(buffer, "}\n"); + + for (i = 0; i < hs->phases.fork_count; ++i) + { + if (FAILED(shader_glsl_generate_shader_phase(shader, buffer, reg_maps, &priv_ctx, + &hs->phases.fork[i], "fork", i))) + return 0; + } + + for (i = 0; i < hs->phases.join_count; ++i) + { + if (FAILED(shader_glsl_generate_shader_phase(shader, buffer, reg_maps, &priv_ctx, + &hs->phases.join[i], "join", i))) + return 0; + } + + shader_addline(buffer, "void main()\n{\n"); + shader_addline(buffer, "hs_control_point_phase();\n"); + if (reg_maps->vocp) + shader_addline(buffer, "barrier();\n"); + for (i = 0; i < hs->phases.fork_count; ++i) + shader_glsl_generate_shader_phase_invocation(buffer, &hs->phases.fork[i], "fork", i); + for (i = 0; i < hs->phases.join_count; ++i) + shader_glsl_generate_shader_phase_invocation(buffer, &hs->phases.join[i], "join", i); + shader_addline(buffer, "setup_patch_constant_output();\n"); + shader_addline(buffer, "}\n"); + + shader_id = GL_EXTCALL(glCreateShader(GL_TESS_CONTROL_SHADER)); + TRACE("Compiling shader object %u.\n", shader_id); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); + + return shader_id; +} + +static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_info, + struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, + const struct ds_compile_args *args) +{ + shader_addline(buffer, "setup_ds_output(ds_out);\n"); + + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) + shader_glsl_fixup_position(buffer); +} + +static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct ds_compile_args *args) +{ + struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct shader_glsl_ctx_priv priv_ctx; + GLuint shader_id; + + memset(&priv_ctx, 0, sizeof(priv_ctx)); + priv_ctx.cur_ds_args = args; + priv_ctx.string_buffers = string_buffers; + + shader_glsl_add_version_declaration(buffer, gl_info); + + shader_glsl_enable_extensions(buffer, gl_info); + shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n"); + + shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + + shader_addline(buffer, "layout("); + switch (shader->u.ds.tessellator_domain) + { + case WINED3D_TESSELLATOR_DOMAIN_LINE: + shader_addline(buffer, "isolines"); + break; + case WINED3D_TESSELLATOR_DOMAIN_QUAD: + shader_addline(buffer, "quads"); + break; + case WINED3D_TESSELLATOR_DOMAIN_TRIANGLE: + shader_addline(buffer, "triangles"); + break; + } + switch (args->tessellator_output_primitive) + { + case WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CW: + if (args->render_offscreen) + shader_addline(buffer, ", ccw"); + else + shader_addline(buffer, ", cw"); + break; + case WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW: + if (args->render_offscreen) + shader_addline(buffer, ", cw"); + else + shader_addline(buffer, ", ccw"); + break; + case WINED3D_TESSELLATOR_OUTPUT_POINT: + shader_addline(buffer, ", point_mode"); + break; + case WINED3D_TESSELLATOR_OUTPUT_LINE: + break; + } + switch (args->tessellator_partitioning) + { + case WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: + shader_addline(buffer, ", fractional_odd_spacing"); + break; + case WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: + shader_addline(buffer, ", fractional_even_spacing"); + break; + case WINED3D_TESSELLATOR_PARTITIONING_INTEGER: + case WINED3D_TESSELLATOR_PARTITIONING_POW2: + shader_addline(buffer, ", equal_spacing"); + break; + } + shader_addline(buffer, ") in;\n"); + + shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input); + + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); + + shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info, + args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL); + shader_glsl_generate_patch_constant_setup(buffer, &shader->patch_constant_signature, TRUE); + + shader_addline(buffer, "void main()\n{\n"); + shader_addline(buffer, "setup_patch_constant_input();\n"); + + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; + + shader_addline(buffer, "}\n"); + + shader_id = GL_EXTCALL(glCreateShader(GL_TESS_EVALUATION_SHADER)); TRACE("Compiling shader object %u.\n", shader_id); shader_glsl_compile(gl_info, shader_id, buffer->buffer); @@ -5561,36 +7754,111 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context /* Context activation is done by the caller. */ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context *context, - struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, - const struct wined3d_shader *shader) + struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct gs_compile_args *args) { + struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers; const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; const struct wined3d_gl_info *gl_info = context->gl_info; - const DWORD *function = shader->function; struct shader_glsl_ctx_priv priv_ctx; GLuint shader_id; + memset(&priv_ctx, 0, sizeof(priv_ctx)); + priv_ctx.string_buffers = string_buffers; + + shader_glsl_add_version_declaration(buffer, gl_info); + + shader_glsl_enable_extensions(buffer, gl_info); + + shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + + shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type)); + if (shader->u.gs.instance_count > 1) + shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count); + shader_addline(buffer, ") in;\n"); + shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n", + glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out); + shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input); + + if (!gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); + + shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info, TRUE); + shader_addline(buffer, "void main()\n{\n"); + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) + return 0; + shader_addline(buffer, "}\n"); + shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER)); + TRACE("Compiling shader object %u.\n", shader_id); + shader_glsl_compile(gl_info, shader_id, buffer->buffer); - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, ®_maps->shader_version)); + return shader_id; +} - if (gl_info->supported[ARB_GEOMETRY_SHADER4]) - shader_addline(buffer, "#extension GL_ARB_geometry_shader4 : enable\n"); - if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) - shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); - if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) - shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); - if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) - shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); - if (gl_info->supported[EXT_GPU_SHADER4]) - shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); +static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx) +{ + const struct shader_glsl_ctx_priv *priv = ctx->backend_data; + const struct wined3d_gl_info *gl_info = ctx->gl_info; + struct wined3d_string_buffer *buffer = ctx->buffer; + const struct wined3d_shader *shader = ctx->shader; + + switch (shader->reg_maps.shader_version.type) + { + case WINED3D_SHADER_TYPE_PIXEL: + shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args); + break; + case WINED3D_SHADER_TYPE_VERTEX: + shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, priv->cur_vs_args); + break; + case WINED3D_SHADER_TYPE_DOMAIN: + shader_glsl_generate_ds_epilogue(gl_info, buffer, shader, priv->cur_ds_args); + break; + case WINED3D_SHADER_TYPE_GEOMETRY: + case WINED3D_SHADER_TYPE_COMPUTE: + break; + default: + FIXME("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type); + break; + } +} + +/* Context activation is done by the caller. */ +static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context *context, + struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, + const struct wined3d_shader *shader) +{ + const struct wined3d_shader_thread_group_size *thread_group_size = &shader->u.cs.thread_group_size; + const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct shader_glsl_ctx_priv priv_ctx; + GLuint shader_id; + unsigned int i; memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.string_buffers = string_buffers; + + shader_glsl_add_version_declaration(buffer, gl_info); + + shader_glsl_enable_extensions(buffer, gl_info); + shader_addline(buffer, "#extension GL_ARB_compute_shader : enable\n"); + shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); - shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); + + for (i = 0; i < reg_maps->tgsm_count; ++i) + { + if (reg_maps->tgsm[i].size) + shader_addline(buffer, "shared uint cs_g%u[%u];\n", i, reg_maps->tgsm[i].size); + } + + shader_addline(buffer, "layout(local_size_x = %u, local_size_y = %u, local_size_z = %u) in;\n", + thread_group_size->x, thread_group_size->y, thread_group_size->z); + + shader_addline(buffer, "void main()\n{\n"); + shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL); shader_addline(buffer, "}\n"); + shader_id = GL_EXTCALL(glCreateShader(GL_COMPUTE_SHADER)); TRACE("Compiling shader object %u.\n", shader_id); shader_glsl_compile(gl_info, shader_id, buffer->buffer); @@ -5684,13 +7952,15 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str return FALSE; if (stored->flatshading != new->flatshading) return FALSE; + if (stored->next_shader_type != new->next_shader_type) + return FALSE; + if (stored->next_shader_input_count != new->next_shader_input_count) + return FALSE; return stored->fog_src == new->fog_src; } -static GLuint find_glsl_vshader(const struct wined3d_context *context, - struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, - struct wined3d_shader *shader, - const struct vs_compile_args *args) +static GLuint find_glsl_vshader(const struct wined3d_context *context, struct shader_glsl_priv *priv, + struct wined3d_shader *shader, const struct vs_compile_args *args) { UINT i; DWORD new_size; @@ -5747,19 +8017,121 @@ static GLuint find_glsl_vshader(const struct wined3d_context *context, gl_shaders[shader_data->num_gl_shaders].args = *args; - string_buffer_clear(buffer); - ret = shader_glsl_generate_vshader(context, buffer, string_buffers, shader, args); + string_buffer_clear(&priv->shader_buffer); + ret = shader_glsl_generate_vshader(context, priv, shader, args); + gl_shaders[shader_data->num_gl_shaders++].id = ret; + + return ret; +} + +static GLuint find_glsl_hull_shader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, struct wined3d_shader *shader) +{ + struct glsl_hs_compiled_shader *gl_shaders, *new_array; + struct glsl_shader_private *shader_data; + unsigned int new_size; + GLuint ret; + + if (!shader->backend_data) + { + if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data)))) + { + ERR("Failed to allocate backend data.\n"); + return 0; + } + } + shader_data = shader->backend_data; + gl_shaders = shader_data->gl_shaders.hs; + + if (shader_data->num_gl_shaders > 0) + { + assert(shader_data->num_gl_shaders == 1); + return gl_shaders[0].id; + } + + TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader); + + assert(!shader_data->gl_shaders.hs); + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + new_size = 1; + if (!new_array) + { + ERR("Failed to allocate GL shaders array.\n"); + return 0; + } + shader_data->gl_shaders.hs = new_array; + shader_data->shader_array_size = new_size; + gl_shaders = new_array; + + string_buffer_clear(&priv->shader_buffer); + ret = shader_glsl_generate_hull_shader(context, priv, shader); + gl_shaders[shader_data->num_gl_shaders++].id = ret; + + return ret; +} + +static GLuint find_glsl_domain_shader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct ds_compile_args *args) +{ + struct glsl_ds_compiled_shader *gl_shaders, *new_array; + struct glsl_shader_private *shader_data; + unsigned int i, new_size; + GLuint ret; + + if (!shader->backend_data) + { + if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data)))) + { + ERR("Failed to allocate backend data.\n"); + return 0; + } + } + shader_data = shader->backend_data; + gl_shaders = shader_data->gl_shaders.ds; + + for (i = 0; i < shader_data->num_gl_shaders; ++i) + { + if (!memcmp(&gl_shaders[i].args, args, sizeof(*args))) + return gl_shaders[i].id; + } + + TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader); + + if (shader_data->num_gl_shaders) + { + new_size = shader_data->shader_array_size + 1; + new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.ds, + new_size * sizeof(*new_array)); + } + else + { + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + new_size = 1; + } + + if (!new_array) + { + ERR("Failed to allocate GL shaders array.\n"); + return 0; + } + shader_data->gl_shaders.ds = new_array; + shader_data->shader_array_size = new_size; + gl_shaders = new_array; + + string_buffer_clear(&priv->shader_buffer); + ret = shader_glsl_generate_domain_shader(context, priv, shader, args); + gl_shaders[shader_data->num_gl_shaders].args = *args; gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; } static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, - struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, - struct wined3d_shader *shader) + struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct gs_compile_args *args) { - struct glsl_gs_compiled_shader *gl_shaders; + struct glsl_gs_compiled_shader *gl_shaders, *new_array; struct glsl_shader_private *shader_data; + unsigned int i, new_size; GLuint ret; if (!shader->backend_data) @@ -5773,21 +8145,38 @@ static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, shader_data = shader->backend_data; gl_shaders = shader_data->gl_shaders.gs; - if (shader_data->num_gl_shaders) - return gl_shaders[0].id; + for (i = 0; i < shader_data->num_gl_shaders; ++i) + { + if (!memcmp(&gl_shaders[i].args, args, sizeof(*args))) + return gl_shaders[i].id; + } TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader); - if (!(shader_data->gl_shaders.gs = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders)))) + if (shader_data->num_gl_shaders) { - ERR("Failed to allocate GL shader array.\n"); + new_size = shader_data->shader_array_size + 1; + new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.gs, + new_size * sizeof(*new_array)); + } + else + { + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + new_size = 1; + } + + if (!new_array) + { + ERR("Failed to allocate GL shaders array.\n"); return 0; } - shader_data->shader_array_size = 1; - gl_shaders = shader_data->gl_shaders.gs; + shader_data->gl_shaders.gs = new_array; + shader_data->shader_array_size = new_size; + gl_shaders = new_array; - string_buffer_clear(buffer); - ret = shader_glsl_generate_geometry_shader(context, buffer, string_buffers, shader); + string_buffer_clear(&priv->shader_buffer); + ret = shader_glsl_generate_geometry_shader(context, priv, shader, args); + gl_shaders[shader_data->num_gl_shaders].args = *args; gl_shaders[shader_data->num_gl_shaders++].id = ret; return ret; @@ -5809,12 +8198,24 @@ static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, c } } +static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer *buffer, + const struct wined3d_ffp_vs_settings *settings, unsigned int idx) +{ + shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" + " * ffp_light[%u].diffuse.xyz * att;\n", idx); + if (settings->localviewer) + shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); + else + shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); + shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0) specular +=" + " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", idx); +} + static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer, const struct wined3d_ffp_vs_settings *settings, BOOL legacy_lighting) { const char *diffuse, *specular, *emissive, *ambient; - enum wined3d_light_type light_type; - unsigned int i; + unsigned int i, idx; if (!settings->lighting) { @@ -5834,131 +8235,97 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer specular = shader_glsl_ffp_mcs(settings->specular_source, "ffp_material.specular"); emissive = shader_glsl_ffp_mcs(settings->emissive_source, "ffp_material.emissive"); - for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) + idx = 0; + for (i = 0; i < settings->point_light_count; ++i, ++idx) { - light_type = (settings->light_type >> WINED3D_FFP_LIGHT_TYPE_SHIFT(i)) & WINED3D_FFP_LIGHT_TYPE_MASK; - switch (light_type) + shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", idx); + shader_addline(buffer, "dst.z = dot(dir, dir);\n"); + shader_addline(buffer, "dst.y = sqrt(dst.z);\n"); + shader_addline(buffer, "dst.x = 1.0;\n"); + if (legacy_lighting) { - case WINED3D_LIGHT_POINT: - shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", i); - shader_addline(buffer, "dst.z = dot(dir, dir);\n"); - shader_addline(buffer, "dst.y = sqrt(dst.z);\n"); - shader_addline(buffer, "dst.x = 1.0;\n"); - if (legacy_lighting) - { - shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", i, i); - shader_addline(buffer, "dst.z = dst.y * dst.y;\n"); - } - else - { - shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", i); - } - shader_addline(buffer, "att = dot(dst.xyz, vec3(ffp_light[%u].c_att," - " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", i, i, i); - if (!legacy_lighting) - shader_addline(buffer, "att = 1.0 / att;\n"); - shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", i); - if (!settings->normal) - { - if (!legacy_lighting) - shader_addline(buffer, "}\n"); - break; - } - shader_addline(buffer, "dir = normalize(dir);\n"); - shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)" - " * ffp_light[%u].diffuse.xyz) * att;\n", i); - if (settings->localviewer) - shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); - else - shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); - shader_addline(buffer, "if (t > 0.0) specular += (pow(t, ffp_material.shininess)" - " * ffp_light[%u].specular) * att;\n", i); - if (!legacy_lighting) - shader_addline(buffer, "}\n"); - break; - - case WINED3D_LIGHT_SPOT: - shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", i); - shader_addline(buffer, "dst.z = dot(dir, dir);\n"); - shader_addline(buffer, "dst.y = sqrt(dst.z);\n"); - shader_addline(buffer, "dst.x = 1.0;\n"); - if (legacy_lighting) - { - shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", i, i); - shader_addline(buffer, "dst.z = dst.y * dst.y;\n"); - } - else - { - shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", i); - } - shader_addline(buffer, "dir = normalize(dir);\n"); - shader_addline(buffer, "t = dot(-dir, normalize(ffp_light[%u].direction));\n", i); - shader_addline(buffer, "if (t > ffp_light[%u].cos_htheta) att = 1.0;\n", i); - shader_addline(buffer, "else if (t <= ffp_light[%u].cos_hphi) att = 0.0;\n", i); - shader_addline(buffer, "else att = pow((t - ffp_light[%u].cos_hphi)" - " / (ffp_light[%u].cos_htheta - ffp_light[%u].cos_hphi), ffp_light[%u].falloff);\n", - i, i, i, i); - if (legacy_lighting) - shader_addline(buffer, "att *= dot(dst.xyz, vec3(ffp_light[%u].c_att," - " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", - i, i, i); - else - shader_addline(buffer, "att /= dot(dst.xyz, vec3(ffp_light[%u].c_att," - " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", - i, i, i); - shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", i); - if (!settings->normal) - { - if (!legacy_lighting) - shader_addline(buffer, "}\n"); - break; - } - shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)" - " * ffp_light[%u].diffuse.xyz) * att;\n", i); - if (settings->localviewer) - shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); - else - shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); - shader_addline(buffer, "if (t > 0.0) specular += (pow(t, ffp_material.shininess)" - " * ffp_light[%u].specular) * att;\n", i); - if (!legacy_lighting) - shader_addline(buffer, "}\n"); - break; - - case WINED3D_LIGHT_DIRECTIONAL: - shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", i); - if (!settings->normal) - break; - shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", i); - shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" - " * ffp_light[%u].diffuse.xyz;\n", i); - /* TODO: In the non-local viewer case the halfvector is constant - * and could be precomputed and stored in a uniform. */ - if (settings->localviewer) - shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); - else - shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); - shader_addline(buffer, "if (t > 0.0) specular += pow(t, ffp_material.shininess)" - " * ffp_light[%u].specular;\n", i); - break; - - case WINED3D_LIGHT_PARALLELPOINT: - shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", i); - if (!settings->normal) - break; - shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", i); - shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" - " * ffp_light[%u].diffuse.xyz;\n", i); - shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); - shader_addline(buffer, "if (t > 0.0) specular += pow(t, ffp_material.shininess)" - " * ffp_light[%u].specular;\n", i); - break; - - default: - if (light_type) - FIXME("Unhandled light type %#x.\n", light_type); - continue; + shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", idx, idx); + shader_addline(buffer, "dst.z = dst.y * dst.y;\n"); + shader_addline(buffer, "if (dst.y > 0.0)\n{\n"); } + else + { + shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", idx); + } + shader_addline(buffer, "att = dot(dst.xyz, vec3(ffp_light[%u].c_att," + " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", idx, idx, idx); + if (!legacy_lighting) + shader_addline(buffer, "att = 1.0 / att;\n"); + shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", idx); + if (!settings->normal) + { + shader_addline(buffer, "}\n"); + continue; + } + shader_addline(buffer, "dir = normalize(dir);\n"); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_addline(buffer, "}\n"); + } + + for (i = 0; i < settings->spot_light_count; ++i, ++idx) + { + shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", idx); + shader_addline(buffer, "dst.z = dot(dir, dir);\n"); + shader_addline(buffer, "dst.y = sqrt(dst.z);\n"); + shader_addline(buffer, "dst.x = 1.0;\n"); + if (legacy_lighting) + { + shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", idx, idx); + shader_addline(buffer, "dst.z = dst.y * dst.y;\n"); + shader_addline(buffer, "if (dst.y > 0.0)\n{\n"); + } + else + { + shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", idx); + } + shader_addline(buffer, "dir = normalize(dir);\n"); + shader_addline(buffer, "t = dot(-dir, normalize(ffp_light[%u].direction));\n", idx); + shader_addline(buffer, "if (t > ffp_light[%u].cos_htheta) att = 1.0;\n", idx); + shader_addline(buffer, "else if (t <= ffp_light[%u].cos_hphi) att = 0.0;\n", idx); + shader_addline(buffer, "else att = pow((t - ffp_light[%u].cos_hphi)" + " / (ffp_light[%u].cos_htheta - ffp_light[%u].cos_hphi), ffp_light[%u].falloff);\n", + idx, idx, idx, idx); + if (legacy_lighting) + shader_addline(buffer, "att *= dot(dst.xyz, vec3(ffp_light[%u].c_att," + " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", + idx, idx, idx); + else + shader_addline(buffer, "att /= dot(dst.xyz, vec3(ffp_light[%u].c_att," + " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", + idx, idx, idx); + shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", idx); + if (!settings->normal) + { + shader_addline(buffer, "}\n"); + continue; + } + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + shader_addline(buffer, "}\n"); + } + + for (i = 0; i < settings->directional_light_count; ++i, ++idx) + { + shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx); + if (!settings->normal) + continue; + shader_addline(buffer, "att = 1.0;\n"); + shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); + } + + for (i = 0; i < settings->parallel_point_light_count; ++i, ++idx) + { + shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx); + if (!settings->normal) + continue; + shader_addline(buffer, "att = 1.0;\n"); + shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", idx); + shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx); } shader_addline(buffer, "ffp_varying_diffuse.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n", @@ -5987,22 +8354,27 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */ {"vec4", "ffp_attrib_specular"}, /* WINED3D_FFP_SPECULAR */ }; + const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); struct wined3d_string_buffer *buffer = &priv->shader_buffer; + BOOL output_legacy_fogcoord = legacy_syntax; BOOL legacy_lighting = priv->legacy_lighting; GLuint shader_obj; unsigned int i; - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; - BOOL output_legacy_fogcoord = legacy_context; string_buffer_clear(buffer); - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, NULL)); + shader_glsl_add_version_declaration(buffer, gl_info); + + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); for (i = 0; i < WINED3D_FFP_ATTRIBS_COUNT; ++i) { const char *type = i < ARRAY_SIZE(attrib_info) ? attrib_info[i].type : "vec4"; - shader_addline(buffer, "attribute %s vs_in%u;\n", type, i); + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = %u) ", i); + shader_addline(buffer, "%s %s vs_in%u;\n", get_attribute_keyword(gl_info), type, i); } shader_addline(buffer, "\n"); @@ -6047,7 +8419,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "} ffp_point;\n"); } - if (legacy_context) + if (legacy_syntax) { shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); shader_addline(buffer, "vec4 ffp_varying_specular;\n"); @@ -6056,6 +8428,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } else { + if (settings->clipping) + shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances); + declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES); @@ -6069,16 +8444,15 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr for (i = 0; i < ARRAY_SIZE(attrib_info); ++i) { if (attrib_info[i].name[0]) - shader_addline(buffer, "%s %s = vs_in%u;\n", - attrib_info[i].type, attrib_info[i].name, i); + shader_addline(buffer, "%s %s = vs_in%u%s;\n", attrib_info[i].type, attrib_info[i].name, + i, settings->swizzle_map & (1u << i) ? ".zyxw" : ""); } for (i = 0; i < MAX_TEXTURES; ++i) { unsigned int coord_idx = settings->texgen[i] & 0x0000ffff; - if ((settings->texgen[i] & 0xffff0000) == WINED3DTSS_TCI_PASSTHRU) - { + if ((settings->texgen[i] & 0xffff0000) == WINED3DTSS_TCI_PASSTHRU + && settings->texcoords & (1u << i)) shader_addline(buffer, "vec4 ffp_attrib_texcoord%u = vs_in%u;\n", i, coord_idx + WINED3D_FFP_TEXCOORD0); - } } shader_addline(buffer, "ffp_attrib_blendweight[%u] = 1.0;\n", settings->vertexblends); @@ -6100,7 +8474,13 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); if (settings->clipping) - shader_addline(buffer, "gl_ClipVertex = ec_pos;\n"); + { + if (legacy_syntax) + shader_addline(buffer, "gl_ClipVertex = ec_pos;\n"); + else + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + shader_addline(buffer, "gl_ClipDistance[%u] = dot(ec_pos, clip_planes[%u]);\n", i, i); + } shader_addline(buffer, "ec_pos /= ec_pos.w;\n"); } @@ -6122,15 +8502,20 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } shader_glsl_ffp_vertex_lighting(buffer, settings, legacy_lighting); - if (legacy_context) + if (legacy_syntax) { shader_addline(buffer, "gl_FrontColor = ffp_varying_diffuse;\n"); shader_addline(buffer, "gl_FrontSecondaryColor = ffp_varying_specular;\n"); } + else + { + shader_addline(buffer, "ffp_varying_diffuse = clamp(ffp_varying_diffuse, 0.0, 1.0);\n"); + shader_addline(buffer, "ffp_varying_specular = clamp(ffp_varying_specular, 0.0, 1.0);\n"); + } for (i = 0; i < MAX_TEXTURES; ++i) { - BOOL output_legacy_texcoord = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + BOOL output_legacy_texcoord = legacy_syntax; switch (settings->texgen[i] & 0xffff0000) { @@ -6188,12 +8573,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr case WINED3D_FFP_VS_FOG_DEPTH: if (settings->ortho_fog) - /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */ - shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n"); + { + if (gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z;\n"); + else + /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */ + shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n"); + } else if (settings->transformed) + { shader_addline(buffer, "ffp_varying_fogcoord = ec_pos.z;\n"); + } else + { shader_addline(buffer, "ffp_varying_fogcoord = abs(ec_pos.z);\n"); + } break; default: @@ -6464,17 +8858,19 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un /* Context activation is done by the caller. */ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv, - const struct ffp_frag_settings *settings, const struct wined3d_gl_info *gl_info) + const struct ffp_frag_settings *settings, const struct wined3d_context *context) { + struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers); + enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1; struct wined3d_string_buffer *buffer = &priv->shader_buffer; BYTE lum_map = 0, bump_map = 0, tex_map = 0, tss_const_map = 0; + const struct wined3d_gl_info *gl_info = context->gl_info; + const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); BOOL tempreg_used = FALSE, tfactor_used = FALSE; UINT lowest_disabled_stage; GLuint shader_id; DWORD arg0, arg1, arg2; unsigned int stage; - struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers); - BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; string_buffer_clear(buffer); @@ -6539,11 +8935,22 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * } lowest_disabled_stage = stage; - shader_addline(buffer, "%s\n", shader_glsl_get_version(gl_info, NULL)); + shader_glsl_add_version_declaration(buffer, gl_info); + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n"); + if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) + shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n"); if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n"); + if (!needs_legacy_glsl_syntax(gl_info)) + { + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = 0) "); + shader_addline(buffer, "out vec4 ps_out[1];\n"); + } + shader_addline(buffer, "vec4 tmp0, tmp1;\n"); shader_addline(buffer, "vec4 ret;\n"); if (tempreg_used || settings->sRGB_write) @@ -6552,6 +8959,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * for (stage = 0; stage < MAX_TEXTURES; ++stage) { + const char *sampler_type; + if (tss_const_map & (1u << stage)) shader_addline(buffer, "uniform vec4 tss_const%u;\n", stage); @@ -6561,24 +8970,31 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * switch (settings->op[stage].tex_type) { case WINED3D_GL_RES_TYPE_TEX_1D: - shader_addline(buffer, "uniform sampler1D ps_sampler%u;\n", stage); + sampler_type = "1D"; break; case WINED3D_GL_RES_TYPE_TEX_2D: - shader_addline(buffer, "uniform sampler2D ps_sampler%u;\n", stage); + sampler_type = "2D"; break; case WINED3D_GL_RES_TYPE_TEX_3D: - shader_addline(buffer, "uniform sampler3D ps_sampler%u;\n", stage); + sampler_type = "3D"; break; case WINED3D_GL_RES_TYPE_TEX_CUBE: - shader_addline(buffer, "uniform samplerCube ps_sampler%u;\n", stage); + sampler_type = "Cube"; break; case WINED3D_GL_RES_TYPE_TEX_RECT: - shader_addline(buffer, "uniform sampler2DRect ps_sampler%u;\n", stage); + sampler_type = "2DRect"; break; default: FIXME("Unhandled sampler type %#x.\n", settings->op[stage].tex_type); + sampler_type = NULL; break; } + if (sampler_type) + { + if (shader_glsl_use_layout_binding_qualifier(gl_info)) + shader_glsl_append_sampler_binding_qualifier(buffer, context, NULL, stage); + shader_addline(buffer, "uniform sampler%s ps_sampler%u;\n", sampler_type, stage); + } shader_addline(buffer, "vec4 tex%u;\n", stage); @@ -6614,7 +9030,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, " float scale;\n"); shader_addline(buffer, "} ffp_fog;\n"); - if (legacy_context) + if (alpha_test_func != WINED3D_CMP_ALWAYS) + shader_addline(buffer, "uniform float alpha_test_ref;\n"); + + if (legacy_syntax) { shader_addline(buffer, "vec4 ffp_varying_diffuse;\n"); shader_addline(buffer, "vec4 ffp_varying_specular;\n"); @@ -6633,7 +9052,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "void main()\n{\n"); - if (legacy_context) + if (legacy_syntax) { shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n"); shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n"); @@ -6647,13 +9066,13 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", stage); else if (settings->texcoords_initialized & (1u << stage)) shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n", - stage, legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", stage); + stage, legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", stage); else shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", stage); } } - if (legacy_context && settings->fog != WINED3D_FFP_PS_FOG_OFF) + if (legacy_syntax && settings->fog != WINED3D_FFP_PS_FOG_OFF) shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n"); if (lowest_disabled_stage < 7 && settings->emul_clipplanes) @@ -6746,7 +9165,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * coord_mask = "xyzw"; break; } - if (!needs_legacy_glsl_syntax(gl_info)) + if (!legacy_syntax) texture_function = proj ? "textureProj" : "texture"; if (stage > 0 @@ -6860,12 +9279,15 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * } } - shader_addline(buffer, "gl_FragData[0] = ffp_varying_specular * specular_enable + ret;\n"); + shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable + ret;\n", + get_fragment_output(gl_info)); if (settings->sRGB_write) - shader_glsl_generate_srgb_write_correction(buffer); + shader_glsl_generate_srgb_write_correction(buffer, gl_info); - shader_glsl_generate_fog_code(buffer, settings->fog); + shader_glsl_generate_fog_code(buffer, gl_info, settings->fog); + + shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func); shader_addline(buffer, "}\n"); @@ -6898,7 +9320,7 @@ static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct } static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv, - const struct wined3d_gl_info *gl_info, const struct ffp_frag_settings *args) + const struct ffp_frag_settings *args, const struct wined3d_context *context) { struct glsl_ffp_fragment_shader *glsl_desc; const struct ffp_frag_desc *desc; @@ -6910,7 +9332,7 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str return NULL; glsl_desc->entry.settings = *args; - glsl_desc->id = shader_glsl_generate_ffp_fragment_shader(priv, args, gl_info); + glsl_desc->id = shader_glsl_generate_ffp_fragment_shader(priv, args, context); list_init(&glsl_desc->linked_programs); add_ffp_frag_shader(&priv->ffp_fragment_shaders, &glsl_desc->entry); @@ -6924,29 +9346,26 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * unsigned int i; struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers); - vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, - sizeof(GLuint) * gl_info->limits.glsl_vs_float_constants); for (i = 0; i < vs_c_count; ++i) { string_buffer_sprintf(name, "vs_c[%u]", i); vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - memset(&vs->uniform_f_locations[vs_c_count], 0xff, - (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLuint)); + memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint)); - for (i = 0; i < MAX_CONST_I; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { string_buffer_sprintf(name, "vs_i[%u]", i); vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - for (i = 0; i < MAX_CONST_B; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { string_buffer_sprintf(name, "vs_b[%u]", i); vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "posFixup")); + vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); for (i = 0; i < MAX_VERTEX_BLENDS; ++i) { @@ -6999,33 +9418,43 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->pointsize_c_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.c_att")); vs->pointsize_l_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.l_att")); vs->pointsize_q_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.q_att")); + vs->clip_planes_location = GL_EXTCALL(glGetUniformLocation(program_id, "clip_planes")); string_buffer_release(&priv->string_buffers, name); } +static void shader_glsl_init_ds_uniform_locations(const struct wined3d_gl_info *gl_info, + struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ds_program *ds) +{ + ds->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); +} + +static void shader_glsl_init_gs_uniform_locations(const struct wined3d_gl_info *gl_info, + struct shader_glsl_priv *priv, GLuint program_id, struct glsl_gs_program *gs) +{ + gs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); +} + static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count) { unsigned int i; struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers); - ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0, - sizeof(GLuint) * gl_info->limits.glsl_ps_float_constants); for (i = 0; i < ps_c_count; ++i) { string_buffer_sprintf(name, "ps_c[%u]", i); ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - memset(&ps->uniform_f_locations[ps_c_count], 0xff, - (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLuint)); + memset(&ps->uniform_f_locations[ps_c_count], 0xff, (WINED3D_MAX_PS_CONSTS_F - ps_c_count) * sizeof(GLuint)); - for (i = 0; i < MAX_CONST_I; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { string_buffer_sprintf(name, "ps_i[%u]", i); ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } - for (i = 0; i < MAX_CONST_B; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { string_buffer_sprintf(name, "ps_b[%u]", i); ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); @@ -7051,6 +9480,8 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info * ps->fog_end_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.end")); ps->fog_scale_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.scale")); + ps->alpha_test_ref_location = GL_EXTCALL(glGetUniformLocation(program_id, "alpha_test_ref")); + ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup")); ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection")); ps->color_key_location = GL_EXTCALL(glGetUniformLocation(program_id, "color_key")); @@ -7058,26 +9489,128 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info * string_buffer_release(&priv->string_buffers, name); } -static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, - struct shader_glsl_priv *priv, GLuint program_id, - const struct wined3d_shader_reg_maps *reg_maps, unsigned int base, unsigned int count) +static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, + const struct wined3d_context *context, struct wined3d_shader *shader) { - const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type); - GLuint block_idx; - unsigned int i; - struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers); + struct glsl_context_data *ctx_data = context->shader_backend_data; + struct wined3d_string_buffer *buffer = &priv->shader_buffer; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct glsl_cs_compiled_shader *gl_shaders; + struct glsl_shader_private *shader_data; + struct glsl_shader_prog_link *entry; + GLuint shader_id, program_id; - for (i = 0; i < count; ++i) + if (!(entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)))) { - if (!reg_maps->cb_sizes[i]) - continue; - - string_buffer_sprintf(name, "block_%s_cb%u", prefix, i); - block_idx = GL_EXTCALL(glGetUniformBlockIndex(program_id, name->buffer)); - GL_EXTCALL(glUniformBlockBinding(program_id, block_idx, base + i)); + ERR("Out of memory.\n"); + return E_OUTOFMEMORY; } - checkGLcall("glUniformBlockBinding"); - string_buffer_release(&priv->string_buffers, name); + + if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data)))) + { + ERR("Failed to allocate backend data.\n"); + HeapFree(GetProcessHeap(), 0, entry); + return E_OUTOFMEMORY; + } + shader_data = shader->backend_data; + gl_shaders = shader_data->gl_shaders.cs; + + if (!(shader_data->gl_shaders.cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders)))) + { + ERR("Failed to allocate GL shader array.\n"); + HeapFree(GetProcessHeap(), 0, entry); + HeapFree(GetProcessHeap(), 0, shader->backend_data); + shader->backend_data = NULL; + return E_OUTOFMEMORY; + } + shader_data->shader_array_size = 1; + gl_shaders = shader_data->gl_shaders.cs; + + TRACE("Compiling compute shader %p.\n", shader); + + string_buffer_clear(buffer); + shader_id = shader_glsl_generate_compute_shader(context, buffer, &priv->string_buffers, shader); + gl_shaders[shader_data->num_gl_shaders++].id = shader_id; + + program_id = GL_EXTCALL(glCreateProgram()); + TRACE("Created new GLSL shader program %u.\n", program_id); + + entry->id = program_id; + entry->vs.id = 0; + entry->hs.id = 0; + entry->ds.id = 0; + entry->gs.id = 0; + entry->ps.id = 0; + entry->cs.id = shader_id; + entry->constant_version = 0; + entry->ps.np2_fixup_info = NULL; + add_glsl_program_entry(priv, entry); + + TRACE("Attaching GLSL shader object %u to program %u.\n", shader_id, program_id); + GL_EXTCALL(glAttachShader(program_id, shader_id)); + checkGLcall("glAttachShader"); + + list_add_head(&shader->linked_programs, &entry->cs.shader_entry); + + TRACE("Linking GLSL shader program %u.\n", program_id); + GL_EXTCALL(glLinkProgram(program_id)); + shader_glsl_validate_link(gl_info, program_id); + + GL_EXTCALL(glUseProgram(program_id)); + checkGLcall("glUseProgram"); + shader_glsl_load_program_resources(context, priv, program_id, shader); + shader_glsl_load_images(gl_info, priv, program_id, &shader->reg_maps); + + entry->constant_update_mask = 0; + + GL_EXTCALL(glUseProgram(ctx_data->glsl_program ? ctx_data->glsl_program->id : 0)); + checkGLcall("glUseProgram"); + return WINED3D_OK; +} + +static GLuint find_glsl_compute_shader(const struct wined3d_context *context, + struct shader_glsl_priv *priv, struct wined3d_shader *shader) +{ + struct glsl_shader_private *shader_data; + + if (!shader->backend_data) + { + WARN("Failed to find GLSL program for compute shader %p.\n", shader); + if (FAILED(shader_glsl_compile_compute_shader(priv, context, shader))) + { + ERR("Failed to compile compute shader %p.\n", shader); + return 0; + } + } + shader_data = shader->backend_data; + return shader_data->gl_shaders.cs[0].id; +} + +/* Context activation is done by the caller. */ +static void set_glsl_compute_shader_program(const struct wined3d_context *context, + const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data) +{ + struct glsl_shader_prog_link *entry; + struct wined3d_shader *shader; + struct glsl_program_key key; + GLuint cs_id; + + if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE))) + return; + + if (!(shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE])) + { + WARN("Compute shader is NULL.\n"); + ctx_data->glsl_program = NULL; + return; + } + + cs_id = find_glsl_compute_shader(context, priv, shader); + memset(&key, 0, sizeof(key)); + key.cs_id = cs_id; + if (!(entry = get_glsl_program_entry(priv, &key))) + ERR("Failed to find GLSL program for compute shader %p.\n", shader); + ctx_data->glsl_program = entry; } /* Context activation is done by the caller. */ @@ -7088,13 +9621,16 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const const struct wined3d_d3d_info *d3d_info = context->d3d_info; const struct ps_np2fixup_info *np2fixup_info = NULL; struct glsl_shader_prog_link *entry = NULL; + struct wined3d_shader *hshader, *dshader, *gshader; struct wined3d_shader *vshader = NULL; - struct wined3d_shader *gshader = NULL; struct wined3d_shader *pshader = NULL; - GLuint program_id; GLuint reorder_shader_id = 0; + struct glsl_program_key key; + GLuint program_id; unsigned int i; GLuint vs_id = 0; + GLuint hs_id = 0; + GLuint ds_id = 0; GLuint gs_id = 0; GLuint ps_id = 0; struct list *ps_list = NULL, *vs_list = NULL; @@ -7107,16 +9643,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const vs_list = &ctx_data->glsl_program->vs.shader_entry; if (use_vs(state)) - { vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; - - if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY)) - && ctx_data->glsl_program->gs.id) - gs_id = ctx_data->glsl_program->gs.id; - else if (gshader) - gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, &priv->string_buffers, gshader); - } } else if (use_vs(state)) { @@ -7125,11 +9652,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, d3d_info); - vs_id = find_glsl_vshader(context, &priv->shader_buffer, &priv->string_buffers, vshader, &vs_compile_args); + vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args); vs_list = &vshader->linked_programs; - - if ((gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY])) - gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, &priv->string_buffers, gshader); } else if (priv->vertex_pipe == &glsl_vertex_pipe) { @@ -7142,6 +9666,38 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const vs_list = &ffp_shader->linked_programs; } + hshader = state->shader[WINED3D_SHADER_TYPE_HULL]; + if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program) + hs_id = ctx_data->glsl_program->hs.id; + else if (hshader) + hs_id = find_glsl_hull_shader(context, priv, hshader); + + dshader = state->shader[WINED3D_SHADER_TYPE_DOMAIN]; + if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_DOMAIN)) && ctx_data->glsl_program) + { + ds_id = ctx_data->glsl_program->ds.id; + } + else if (dshader) + { + struct ds_compile_args args; + + find_ds_compile_args(state, dshader, &args, context); + ds_id = find_glsl_domain_shader(context, priv, dshader, &args); + } + + gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]; + if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY)) && ctx_data->glsl_program) + { + gs_id = ctx_data->glsl_program->gs.id; + } + else if (gshader) + { + struct gs_compile_args args; + + find_gs_compile_args(state, gshader, &args); + gs_id = find_glsl_geometry_shader(context, priv, gshader, &args); + } + if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program) { ps_id = ctx_data->glsl_program->ps.id; @@ -7159,18 +9715,25 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const pshader, &ps_compile_args, &np2fixup_info); ps_list = &pshader->linked_programs; } - else if (priv->fragment_pipe == &glsl_fragment_pipe) + else if (priv->fragment_pipe == &glsl_fragment_pipe + && !(vshader && vshader->reg_maps.shader_version.major >= 4)) { struct glsl_ffp_fragment_shader *ffp_shader; struct ffp_frag_settings settings; gen_ffp_frag_op(context, state, &settings, FALSE); - ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, gl_info, &settings); + ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, &settings, context); ps_id = ffp_shader->id; ps_list = &ffp_shader->linked_programs; } - if ((!vs_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, vs_id, gs_id, ps_id))) + key.vs_id = vs_id; + key.hs_id = hs_id; + key.ds_id = ds_id; + key.gs_id = gs_id; + key.ps_id = ps_id; + key.cs_id = 0; + if ((!vs_id && !hs_id && !ds_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, &key))) { ctx_data->glsl_program = entry; return; @@ -7184,8 +9747,11 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link)); entry->id = program_id; entry->vs.id = vs_id; + entry->hs.id = hs_id; + entry->ds.id = ds_id; entry->gs.id = gs_id; entry->ps.id = ps_id; + entry->cs.id = 0; entry->constant_version = 0; entry->ps.np2_fixup_info = np2fixup_info; /* Add the hash table entry */ @@ -7207,43 +9773,79 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (vshader) { attribs_map = vshader->reg_maps.input_registers; - reorder_shader_id = generate_param_reorder_function(priv, vshader, pshader, - state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size, - d3d_info->emulated_flatshading - && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info); - TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id); - GL_EXTCALL(glAttachShader(program_id, reorder_shader_id)); - checkGLcall("glAttachShader"); - /* Flag the reorder function for deletion, then it will be freed automatically when the program - * is destroyed - */ - GL_EXTCALL(glDeleteShader(reorder_shader_id)); + if (vshader->reg_maps.shader_version.major < 4) + { + reorder_shader_id = shader_glsl_generate_vs3_rasterizer_input_setup(priv, vshader, pshader, + state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size, + d3d_info->emulated_flatshading + && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info); + TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id); + GL_EXTCALL(glAttachShader(program_id, reorder_shader_id)); + checkGLcall("glAttachShader"); + /* Flag the reorder function for deletion, it will be freed + * automatically when the program is destroyed. */ + GL_EXTCALL(glDeleteShader(reorder_shader_id)); + } } else { attribs_map = (1u << WINED3D_FFP_ATTRIBS_COUNT) - 1; } - /* Bind vertex attributes to a corresponding index number to match - * the same index numbers as ARB_vertex_programs (makes loading - * vertex attributes simpler). With this method, we can use the - * exact same code to load the attributes later for both ARB and - * GLSL shaders. - * - * We have to do this here because we need to know the Program ID - * in order to make the bindings work, and it has to be done prior - * to linking the GLSL program. */ - tmp_name = string_buffer_get(&priv->string_buffers); - for (i = 0; attribs_map; attribs_map >>= 1, ++i) + if (!shader_glsl_use_explicit_attrib_location(gl_info)) { - if (!(attribs_map & 1)) - continue; + /* Bind vertex attributes to a corresponding index number to match + * the same index numbers as ARB_vertex_programs (makes loading + * vertex attributes simpler). With this method, we can use the + * exact same code to load the attributes later for both ARB and + * GLSL shaders. + * + * We have to do this here because we need to know the Program ID + * in order to make the bindings work, and it has to be done prior + * to linking the GLSL program. */ + tmp_name = string_buffer_get(&priv->string_buffers); + for (i = 0; attribs_map; attribs_map >>= 1, ++i) + { + if (!(attribs_map & 1)) + continue; - string_buffer_sprintf(tmp_name, "vs_in%u", i); - GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer)); + string_buffer_sprintf(tmp_name, "vs_in%u", i); + GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer)); + if (vshader && vshader->reg_maps.shader_version.major >= 4) + { + string_buffer_sprintf(tmp_name, "vs_in_uint%u", i); + GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer)); + string_buffer_sprintf(tmp_name, "vs_in_int%u", i); + GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer)); + } + } + checkGLcall("glBindAttribLocation"); + string_buffer_release(&priv->string_buffers, tmp_name); + + if (!needs_legacy_glsl_syntax(gl_info)) + { + GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out")); + checkGLcall("glBindFragDataLocation"); + } + } + + if (hshader) + { + TRACE("Attaching GLSL tessellation control shader object %u to program %u.\n", hs_id, program_id); + GL_EXTCALL(glAttachShader(program_id, hs_id)); + checkGLcall("glAttachShader"); + + list_add_head(&hshader->linked_programs, &entry->hs.shader_entry); + } + + if (dshader) + { + TRACE("Attaching GLSL tessellation evaluation shader object %u to program %u.\n", ds_id, program_id); + GL_EXTCALL(glAttachShader(program_id, ds_id)); + checkGLcall("glAttachShader"); + + list_add_head(&dshader->linked_programs, &entry->ds.shader_entry); } - checkGLcall("glBindAttribLocation"); - string_buffer_release(&priv->string_buffers, tmp_name); if (gshader) { @@ -7251,17 +9853,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GL_EXTCALL(glAttachShader(program_id, gs_id)); checkGLcall("glAttachShader"); - TRACE("input type %s, output type %s, vertices out %u.\n", - debug_d3dprimitivetype(gshader->u.gs.input_type), - debug_d3dprimitivetype(gshader->u.gs.output_type), - gshader->u.gs.vertices_out); - GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_INPUT_TYPE_ARB, - gl_primitive_type_from_d3d(gshader->u.gs.input_type))); - GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_OUTPUT_TYPE_ARB, - gl_primitive_type_from_d3d(gshader->u.gs.output_type))); - GL_EXTCALL(glProgramParameteriARB(program_id, GL_GEOMETRY_VERTICES_OUT_ARB, - gshader->u.gs.vertices_out)); - checkGLcall("glProgramParameteriARB"); + shader_glsl_init_transform_feedback(context, priv, program_id, gshader); list_add_head(&gshader->linked_programs, &entry->gs.shader_entry); } @@ -7282,19 +9874,31 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const shader_glsl_validate_link(gl_info, program_id); shader_glsl_init_vs_uniform_locations(gl_info, priv, program_id, &entry->vs, - vshader ? min(vshader->limits->constant_float, gl_info->limits.glsl_vs_float_constants) : 0); + vshader ? vshader->limits->constant_float : 0); + shader_glsl_init_ds_uniform_locations(gl_info, priv, program_id, &entry->ds); + shader_glsl_init_gs_uniform_locations(gl_info, priv, program_id, &entry->gs); shader_glsl_init_ps_uniform_locations(gl_info, priv, program_id, &entry->ps, - pshader ? min(pshader->limits->constant_float, gl_info->limits.glsl_ps_float_constants) : 0); + pshader ? pshader->limits->constant_float : 0); checkGLcall("Find glsl program uniform locations"); - if (pshader && pshader->reg_maps.shader_version.major >= 3 - && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info)) + if (needs_legacy_glsl_syntax(gl_info)) { - TRACE("Shader %d needs vertex color clamping disabled.\n", program_id); - entry->vs.vertex_color_clamp = GL_FALSE; + if (pshader && pshader->reg_maps.shader_version.major >= 3 + && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info)) + { + TRACE("Shader %d needs vertex color clamping disabled.\n", program_id); + entry->vs.vertex_color_clamp = GL_FALSE; + } + else + { + entry->vs.vertex_color_clamp = GL_FIXED_ONLY_ARB; + } } else { + /* With core profile we never change vertex_color_clamp from + * GL_FIXED_ONLY_MODE (which is also the initial value) so we never call + * glClampColorARB(). */ entry->vs.vertex_color_clamp = GL_FIXED_ONLY_ARB; } @@ -7302,10 +9906,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const GL_EXTCALL(glUseProgram(program_id)); checkGLcall("glUseProgram"); - /* Texture unit mapping is set up to be the same each time the shader - * program is used so we can hardcode the sampler uniform values. */ - shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id); - entry->constant_update_mask = 0; if (vshader) { @@ -7314,10 +9914,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_I; if (vshader->reg_maps.boolean_constants) entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B; - entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + if (entry->vs.pos_fixup_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; - shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &vshader->reg_maps, - 0, gl_info->limits.vertex_uniform_blocks); + shader_glsl_load_program_resources(context, priv, program_id, vshader); } else { @@ -7349,12 +9949,29 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->vs.light_ambient_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_LIGHTS; } + if (entry->vs.clip_planes_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; if (entry->vs.pointsize_min_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; + if (hshader) + shader_glsl_load_program_resources(context, priv, program_id, hshader); + + if (dshader) + { + if (entry->ds.pos_fixup_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; + + shader_glsl_load_program_resources(context, priv, program_id, dshader); + } + if (gshader) - shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &gshader->reg_maps, - gl_info->limits.vertex_uniform_blocks, gl_info->limits.geometry_uniform_blocks); + { + if (entry->gs.pos_fixup_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; + + shader_glsl_load_program_resources(context, priv, program_id, gshader); + } if (ps_id) { @@ -7368,13 +9985,14 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->ps.ycorrection_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; - shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &pshader->reg_maps, - gl_info->limits.vertex_uniform_blocks + gl_info->limits.geometry_uniform_blocks, - gl_info->limits.fragment_uniform_blocks); + shader_glsl_load_program_resources(context, priv, program_id, pshader); + shader_glsl_load_images(gl_info, priv, program_id, &pshader->reg_maps); } else { entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS; + + shader_glsl_load_samplers(context, priv, program_id, NULL); } for (i = 0; i < MAX_TEXTURES; ++i) @@ -7388,6 +10006,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (entry->ps.fog_color_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG; + if (entry->ps.alpha_test_ref_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_ALPHA_TEST; if (entry->ps.np2_fixup_location != -1) entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; if (entry->ps.color_key_location != -1) @@ -7395,123 +10015,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const } } -/* Context activation is done by the caller. */ -static GLuint create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum wined3d_gl_resource_type tex_type, - BOOL masked) +static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *shader) { - GLuint program_id; - GLuint vshader_id, pshader_id; - const char *blt_pshader; + struct wined3d_device *device = shader->device; + struct wined3d_context *context; - static const char blt_vshader[] = - "#version 120\n" - "void main(void)\n" - "{\n" - " gl_Position = gl_Vertex;\n" - " gl_FrontColor = vec4(1.0);\n" - " gl_TexCoord[0] = gl_MultiTexCoord0;\n" - "}\n"; - - static const char * const blt_pshaders_full[WINED3D_GL_RES_TYPE_COUNT] = + if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE) { - /* WINED3D_GL_RES_TYPE_TEX_1D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_2D */ - "#version 120\n" - "uniform sampler2D sampler;\n" - "void main(void)\n" - "{\n" - " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_TEX_3D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_CUBE */ - "#version 120\n" - "uniform samplerCube sampler;\n" - "void main(void)\n" - "{\n" - " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_TEX_RECT */ - "#version 120\n" - "#extension GL_ARB_texture_rectangle : enable\n" - "uniform sampler2DRect sampler;\n" - "void main(void)\n" - "{\n" - " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_BUFFER */ - NULL, - /* WINED3D_GL_RES_TYPE_RB */ - NULL, - }; - - static const char * const blt_pshaders_masked[WINED3D_GL_RES_TYPE_COUNT] = - { - /* WINED3D_GL_RES_TYPE_TEX_1D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_2D */ - "#version 120\n" - "uniform sampler2D sampler;\n" - "uniform vec4 mask;\n" - "void main(void)\n" - "{\n" - " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" - " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_TEX_3D */ - NULL, - /* WINED3D_GL_RES_TYPE_TEX_CUBE */ - "#version 120\n" - "uniform samplerCube sampler;\n" - "uniform vec4 mask;\n" - "void main(void)\n" - "{\n" - " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" - " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_TEX_RECT */ - "#version 120\n" - "#extension GL_ARB_texture_rectangle : enable\n" - "uniform sampler2DRect sampler;\n" - "uniform vec4 mask;\n" - "void main(void)\n" - "{\n" - " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" - " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n" - "}\n", - /* WINED3D_GL_RES_TYPE_BUFFER */ - NULL, - /* WINED3D_GL_RES_TYPE_RB */ - NULL, - }; - - blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type]; - if (!blt_pshader) - { - FIXME("tex_type %#x not supported\n", tex_type); - return 0; + context = context_acquire(device, NULL, 0); + shader_glsl_compile_compute_shader(shader_priv, context, shader); + context_release(context); } - - vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER)); - shader_glsl_compile(gl_info, vshader_id, blt_vshader); - - pshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER)); - shader_glsl_compile(gl_info, pshader_id, blt_pshader); - - program_id = GL_EXTCALL(glCreateProgram()); - GL_EXTCALL(glAttachShader(program_id, vshader_id)); - GL_EXTCALL(glAttachShader(program_id, pshader_id)); - GL_EXTCALL(glLinkProgram(program_id)); - - shader_glsl_validate_link(gl_info, program_id); - - /* Once linked we can mark the shaders for deletion. They will be deleted once the program - * is destroyed - */ - GL_EXTCALL(glDeleteShader(vshader_id)); - GL_EXTCALL(glDeleteShader(pshader_id)); - return program_id; } /* Context activation is done by the caller. */ @@ -7521,22 +10035,13 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex struct glsl_context_data *ctx_data = context->shader_backend_data; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; - GLuint program_id = 0, prev_id = 0; - GLenum old_vertex_color_clamp, current_vertex_color_clamp; + GLenum current_vertex_color_clamp; + GLuint program_id, prev_id; priv->vertex_pipe->vp_enable(gl_info, !use_vs(state)); priv->fragment_pipe->enable_extension(gl_info, !use_ps(state)); - if (ctx_data->glsl_program) - { - prev_id = ctx_data->glsl_program->id; - old_vertex_color_clamp = ctx_data->glsl_program->vs.vertex_color_clamp; - } - else - { - prev_id = 0; - old_vertex_color_clamp = GL_FIXED_ONLY_ARB; - } + prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; set_glsl_shader_program(context, state, priv, ctx_data); @@ -7551,8 +10056,9 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex current_vertex_color_clamp = GL_FIXED_ONLY_ARB; } - if (old_vertex_color_clamp != current_vertex_color_clamp) + if (ctx_data->vertex_color_clamp != current_vertex_color_clamp) { + ctx_data->vertex_color_clamp = current_vertex_color_clamp; if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) { GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, current_vertex_color_clamp)); @@ -7560,7 +10066,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex } else { - FIXME("vertex color clamp needs to be changed, but extension not supported.\n"); + FIXME("Vertex color clamp needs to be changed, but extension not supported.\n"); } } @@ -7574,6 +10080,36 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex if (program_id) context->constant_update_mask |= ctx_data->glsl_program->constant_update_mask; } + + context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE); +} + +/* Context activation is done by the caller. */ +static void shader_glsl_select_compute(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state) +{ + struct glsl_context_data *ctx_data = context->shader_backend_data; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct shader_glsl_priv *priv = shader_priv; + GLuint program_id, prev_id; + + prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; + set_glsl_compute_shader_program(context, state, priv, ctx_data); + program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; + + TRACE("Using GLSL program %u.\n", program_id); + + if (prev_id != program_id) + { + GL_EXTCALL(glUseProgram(program_id)); + checkGLcall("glUseProgram"); + } + + context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_PIXEL) + | (1u << WINED3D_SHADER_TYPE_VERTEX) + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN); } /* "context" is not necessarily the currently active context. */ @@ -7584,12 +10120,16 @@ static void shader_glsl_invalidate_current_program(struct wined3d_context *conte ctx_data->glsl_program = NULL; context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) - | (1u << WINED3D_SHADER_TYPE_GEOMETRY); + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN) + | (1u << WINED3D_SHADER_TYPE_COMPUTE); } /* Context activation is done by the caller. */ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *context) { + struct glsl_context_data *ctx_data = context->shader_backend_data; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; @@ -7600,55 +10140,14 @@ static void shader_glsl_disable(void *shader_priv, struct wined3d_context *conte priv->vertex_pipe->vp_enable(gl_info, FALSE); priv->fragment_pipe->enable_extension(gl_info, FALSE); - if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) + if (needs_legacy_glsl_syntax(gl_info) && gl_info->supported[ARB_COLOR_BUFFER_FLOAT]) { + ctx_data->vertex_color_clamp = GL_FIXED_ONLY_ARB; GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FIXED_ONLY_ARB)); checkGLcall("glClampColorARB"); } } -/* Context activation is done by the caller. */ -static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info, - enum wined3d_gl_resource_type tex_type, const SIZE *ds_mask_size) -{ - BOOL masked = ds_mask_size->cx && ds_mask_size->cy; - struct shader_glsl_priv *priv = shader_priv; - GLuint *blt_program; - GLint loc; - - blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type]; - if (!*blt_program) - { - *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked); - loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "sampler")); - GL_EXTCALL(glUseProgram(*blt_program)); - GL_EXTCALL(glUniform1i(loc, 0)); - } - else - { - GL_EXTCALL(glUseProgram(*blt_program)); - } - - if (masked) - { - loc = GL_EXTCALL(glGetUniformLocation(*blt_program, "mask")); - GL_EXTCALL(glUniform4f(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); - } -} - -/* Context activation is done by the caller. */ -static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) -{ - const struct glsl_context_data *ctx_data = context_get_current()->shader_backend_data; - GLuint program_id; - - program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0; - if (program_id) TRACE("Using GLSL program %u\n", program_id); - - GL_EXTCALL(glUseProgram(program_id)); - checkGLcall("glUseProgram"); -} - static void shader_glsl_invalidate_contexts_program(struct wined3d_device *device, const struct glsl_shader_prog_link *program) { @@ -7682,7 +10181,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) return; } - context = context_acquire(device, NULL); + context = context_acquire(device, NULL, 0); gl_info = context->gl_info; TRACE("Deleting linked programs.\n"); @@ -7738,6 +10237,50 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) break; } + case WINED3D_SHADER_TYPE_HULL: + { + struct glsl_hs_compiled_shader *gl_shaders = shader_data->gl_shaders.hs; + + for (i = 0; i < shader_data->num_gl_shaders; ++i) + { + TRACE("Deleting hull shader %u.\n", gl_shaders[i].id); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); + } + HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.hs); + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, + struct glsl_shader_prog_link, hs.shader_entry) + { + shader_glsl_invalidate_contexts_program(device, entry); + delete_glsl_program_entry(priv, gl_info, entry); + } + + break; + } + + case WINED3D_SHADER_TYPE_DOMAIN: + { + struct glsl_ds_compiled_shader *gl_shaders = shader_data->gl_shaders.ds; + + for (i = 0; i < shader_data->num_gl_shaders; ++i) + { + TRACE("Deleting domain shader %u.\n", gl_shaders[i].id); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); + } + HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ds); + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, + struct glsl_shader_prog_link, ds.shader_entry) + { + shader_glsl_invalidate_contexts_program(device, entry); + delete_glsl_program_entry(priv, gl_info, entry); + } + + break; + } + case WINED3D_SHADER_TYPE_GEOMETRY: { struct glsl_gs_compiled_shader *gl_shaders = shader_data->gl_shaders.gs; @@ -7760,6 +10303,28 @@ static void shader_glsl_destroy(struct wined3d_shader *shader) break; } + case WINED3D_SHADER_TYPE_COMPUTE: + { + struct glsl_cs_compiled_shader *gl_shaders = shader_data->gl_shaders.cs; + + for (i = 0; i < shader_data->num_gl_shaders; ++i) + { + TRACE("Deleting compute shader %u.\n", gl_shaders[i].id); + GL_EXTCALL(glDeleteShader(gl_shaders[i].id)); + checkGLcall("glDeleteShader"); + } + HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.cs); + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, + struct glsl_shader_prog_link, cs.shader_entry) + { + shader_glsl_invalidate_contexts_program(device, entry); + delete_glsl_program_entry(priv, gl_info, entry); + } + + break; + } + default: ERR("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type); break; @@ -7787,6 +10352,15 @@ static int glsl_program_key_compare(const void *key, const struct wine_rb_entry if (k->ps_id > prog->ps.id) return 1; else if (k->ps_id < prog->ps.id) return -1; + if (k->hs_id > prog->hs.id) return 1; + else if (k->hs_id < prog->hs.id) return -1; + + if (k->ds_id > prog->ds.id) return 1; + else if (k->ds_id < prog->ds.id) return -1; + + if (k->cs_id > prog->cs.id) return 1; + else if (k->cs_id < prog->cs.id) return -1; + return 0; } @@ -7823,8 +10397,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv)); - SIZE_T stack_size = wined3d_log2i(max(gl_info->limits.glsl_vs_float_constants, - gl_info->limits.glsl_ps_float_constants)) + 1; + SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1; struct fragment_caps fragment_caps; void *vertex_priv, *fragment_priv; @@ -7851,20 +10424,19 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win goto fail; } - priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack)); - if (!priv->stack) + if (!(priv->stack = wined3d_calloc(stack_size, sizeof(*priv->stack)))) { ERR("Failed to allocate memory.\n"); goto fail; } - if (!constant_heap_init(&priv->vconst_heap, gl_info->limits.glsl_vs_float_constants)) + if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F)) { ERR("Failed to initialize vertex shader constant heap\n"); goto fail; } - if (!constant_heap_init(&priv->pconst_heap, gl_info->limits.glsl_ps_float_constants)) + if (!constant_heap_init(&priv->pconst_heap, WINED3D_MAX_PS_CONSTS_F)) { ERR("Failed to initialize pixel shader constant heap\n"); goto fail; @@ -7899,21 +10471,7 @@ fail: /* Context activation is done by the caller. */ static void shader_glsl_free(struct wined3d_device *device) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct shader_glsl_priv *priv = device->shader_priv; - int i; - - for (i = 0; i < WINED3D_GL_RES_TYPE_COUNT; ++i) - { - if (priv->depth_blt_program_full[i]) - { - GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_full[i])); - } - if (priv->depth_blt_program_masked[i]) - { - GL_EXTCALL(glDeleteProgram(priv->depth_blt_program_masked[i])); - } - } wine_rb_destroy(&priv->program_lookup, NULL, NULL); constant_heap_free(&priv->pconst_heap); @@ -7930,8 +10488,12 @@ static void shader_glsl_free(struct wined3d_device *device) static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context) { - return !!(context->shader_backend_data = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, sizeof(struct glsl_context_data))); + struct glsl_context_data *ctx_data; + if (!(ctx_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ctx_data)))) + return FALSE; + ctx_data->vertex_color_clamp = GL_FIXED_ONLY_ARB; + context->shader_backend_data = ctx_data; + return TRUE; } static void shader_glsl_free_context_data(struct wined3d_context *context) @@ -7949,25 +10511,48 @@ static void shader_glsl_init_context_state(struct wined3d_context *context) static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) { - UINT shader_model; + unsigned int shader_model; - if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[WINED3D_GL_VERSION_3_2] - && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS]) + /* FIXME: Check for the specific extensions required for SM5 support + * (ARB_compute_shader, ARB_tessellation_shader, ARB_gpu_shader5, ...) as + * soon as we introduce them, adjusting the GL / GLSL version checks + * accordingly. */ + if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 30) && gl_info->supported[WINED3D_GL_VERSION_4_3] + && gl_info->supported[ARB_COMPUTE_SHADER] + && gl_info->supported[ARB_DERIVATIVE_CONTROL] + && gl_info->supported[ARB_GPU_SHADER5] + && gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] + && gl_info->supported[ARB_SHADER_IMAGE_LOAD_STORE] + && gl_info->supported[ARB_SHADER_IMAGE_SIZE] + && gl_info->supported[ARB_SHADING_LANGUAGE_PACKING] + && gl_info->supported[ARB_TESSELLATION_SHADER] + && gl_info->supported[ARB_TEXTURE_GATHER] + && gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + shader_model = 5; + else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[WINED3D_GL_VERSION_3_2] + && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS] + && gl_info->supported[ARB_TEXTURE_SWIZZLE]) shader_model = 4; - /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3 - * texldd and texldl instructions. */ - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD] || gl_info->supported[EXT_GPU_SHADER4]) + /* Support for texldd and texldl instructions in pixel shaders is required + * for SM3. */ + else if (shader_glsl_has_core_grad(gl_info) || gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_model = 3; else shader_model = 2; TRACE("Shader model %u.\n", shader_model); caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model); + caps->hs_version = min(wined3d_settings.max_sm_hs, shader_model); + caps->ds_version = min(wined3d_settings.max_sm_ds, shader_model); caps->gs_version = min(wined3d_settings.max_sm_gs, shader_model); caps->ps_version = min(wined3d_settings.max_sm_ps, shader_model); + caps->cs_version = min(wined3d_settings.max_sm_cs, shader_model); - caps->vs_uniform_count = gl_info->limits.glsl_vs_float_constants; - caps->ps_uniform_count = gl_info->limits.glsl_ps_float_constants; + caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0; + caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0; + + caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); + caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); caps->varying_count = gl_info->limits.glsl_varyings; /* FIXME: The following line is card dependent. -8.0 to 8.0 is the @@ -8015,148 +10600,243 @@ static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup) static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = { - /* WINED3DSIH_ABS */ shader_glsl_map2gl, - /* WINED3DSIH_ADD */ shader_glsl_binop, - /* WINED3DSIH_AND */ shader_glsl_binop, - /* WINED3DSIH_BEM */ shader_glsl_bem, - /* WINED3DSIH_BREAK */ shader_glsl_break, - /* WINED3DSIH_BREAKC */ shader_glsl_breakc, - /* WINED3DSIH_BREAKP */ shader_glsl_breakp, - /* WINED3DSIH_CALL */ shader_glsl_call, - /* WINED3DSIH_CALLNZ */ shader_glsl_callnz, - /* WINED3DSIH_CMP */ shader_glsl_conditional_move, - /* WINED3DSIH_CND */ shader_glsl_cnd, - /* WINED3DSIH_CRS */ shader_glsl_cross, - /* WINED3DSIH_CUT */ shader_glsl_cut, - /* WINED3DSIH_DCL */ shader_glsl_nop, - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop, - /* WINED3DSIH_DCL_GLOBAL_FLAGS */ shader_glsl_nop, - /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, - /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_PS */ NULL, - /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, - /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, - /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_SIV */ shader_glsl_nop, - /* WINED3DSIH_DCL_OUTPUT */ shader_glsl_nop, - /* WINED3DSIH_DCL_OUTPUT_SIV */ shader_glsl_nop, - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop, - /* WINED3DSIH_DCL_SAMPLER */ NULL, - /* WINED3DSIH_DCL_TEMPS */ shader_glsl_nop, - /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop, - /* WINED3DSIH_DEF */ shader_glsl_nop, - /* WINED3DSIH_DEFB */ shader_glsl_nop, - /* WINED3DSIH_DEFI */ shader_glsl_nop, - /* WINED3DSIH_DIV */ shader_glsl_binop, - /* WINED3DSIH_DP2 */ shader_glsl_dot, - /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add, - /* WINED3DSIH_DP3 */ shader_glsl_dot, - /* WINED3DSIH_DP4 */ shader_glsl_dot, - /* WINED3DSIH_DST */ shader_glsl_dst, - /* WINED3DSIH_DSX */ shader_glsl_map2gl, - /* WINED3DSIH_DSY */ shader_glsl_map2gl, - /* WINED3DSIH_ELSE */ shader_glsl_else, - /* WINED3DSIH_EMIT */ shader_glsl_emit, - /* WINED3DSIH_ENDIF */ shader_glsl_end, - /* WINED3DSIH_ENDLOOP */ shader_glsl_end, - /* WINED3DSIH_ENDREP */ shader_glsl_end, - /* WINED3DSIH_EQ */ shader_glsl_relop, - /* WINED3DSIH_EXP */ shader_glsl_scalar_op, - /* WINED3DSIH_EXPP */ shader_glsl_expp, - /* WINED3DSIH_FRC */ shader_glsl_map2gl, - /* WINED3DSIH_FTOI */ shader_glsl_to_int, - /* WINED3DSIH_FTOU */ shader_glsl_to_uint, - /* WINED3DSIH_GE */ shader_glsl_relop, - /* WINED3DSIH_IADD */ shader_glsl_binop, - /* WINED3DSIH_IEQ */ shader_glsl_relop, - /* WINED3DSIH_IF */ shader_glsl_if, - /* WINED3DSIH_IFC */ shader_glsl_ifc, - /* WINED3DSIH_IGE */ shader_glsl_relop, - /* WINED3DSIH_ILT */ shader_glsl_relop, - /* WINED3DSIH_IMAD */ shader_glsl_mad, - /* WINED3DSIH_IMAX */ shader_glsl_map2gl, - /* WINED3DSIH_IMIN */ shader_glsl_map2gl, - /* WINED3DSIH_IMUL */ shader_glsl_imul, - /* WINED3DSIH_INE */ shader_glsl_relop, - /* WINED3DSIH_INEG */ shader_glsl_unary_op, - /* WINED3DSIH_ISHL */ shader_glsl_binop, - /* WINED3DSIH_ITOF */ shader_glsl_to_float, - /* WINED3DSIH_LABEL */ shader_glsl_label, - /* WINED3DSIH_LD */ shader_glsl_ld, - /* WINED3DSIH_LIT */ shader_glsl_lit, - /* WINED3DSIH_LOG */ shader_glsl_scalar_op, - /* WINED3DSIH_LOGP */ shader_glsl_scalar_op, - /* WINED3DSIH_LOOP */ shader_glsl_loop, - /* WINED3DSIH_LRP */ shader_glsl_lrp, - /* WINED3DSIH_LT */ shader_glsl_relop, - /* WINED3DSIH_M3x2 */ shader_glsl_mnxn, - /* WINED3DSIH_M3x3 */ shader_glsl_mnxn, - /* WINED3DSIH_M3x4 */ shader_glsl_mnxn, - /* WINED3DSIH_M4x3 */ shader_glsl_mnxn, - /* WINED3DSIH_M4x4 */ shader_glsl_mnxn, - /* WINED3DSIH_MAD */ shader_glsl_mad, - /* WINED3DSIH_MAX */ shader_glsl_map2gl, - /* WINED3DSIH_MIN */ shader_glsl_map2gl, - /* WINED3DSIH_MOV */ shader_glsl_mov, - /* WINED3DSIH_MOVA */ shader_glsl_mov, - /* WINED3DSIH_MOVC */ shader_glsl_conditional_move, - /* WINED3DSIH_MUL */ shader_glsl_binop, - /* WINED3DSIH_NE */ shader_glsl_relop, - /* WINED3DSIH_NOP */ shader_glsl_nop, - /* WINED3DSIH_NOT */ shader_glsl_unary_op, - /* WINED3DSIH_NRM */ shader_glsl_nrm, - /* WINED3DSIH_OR */ shader_glsl_binop, - /* WINED3DSIH_PHASE */ shader_glsl_nop, - /* WINED3DSIH_POW */ shader_glsl_pow, - /* WINED3DSIH_RCP */ shader_glsl_scalar_op, - /* WINED3DSIH_REP */ shader_glsl_rep, - /* WINED3DSIH_RESINFO */ shader_glsl_resinfo, - /* WINED3DSIH_RET */ shader_glsl_ret, - /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, - /* WINED3DSIH_ROUND_PI */ shader_glsl_map2gl, - /* WINED3DSIH_ROUND_Z */ shader_glsl_map2gl, - /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, - /* WINED3DSIH_SAMPLE */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_B */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_C */ NULL, - /* WINED3DSIH_SAMPLE_C_LZ */ NULL, - /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample, - /* WINED3DSIH_SETP */ NULL, - /* WINED3DSIH_SGE */ shader_glsl_compare, - /* WINED3DSIH_SGN */ shader_glsl_sgn, - /* WINED3DSIH_SINCOS */ shader_glsl_sincos, - /* WINED3DSIH_SLT */ shader_glsl_compare, - /* WINED3DSIH_SQRT */ shader_glsl_map2gl, - /* WINED3DSIH_SUB */ shader_glsl_binop, - /* WINED3DSIH_TEX */ shader_glsl_tex, - /* WINED3DSIH_TEXBEM */ shader_glsl_texbem, - /* WINED3DSIH_TEXBEML */ shader_glsl_texbem, - /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord, - /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth, - /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3, - /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex, - /* WINED3DSIH_TEXKILL */ shader_glsl_texkill, - /* WINED3DSIH_TEXLDD */ shader_glsl_texldd, - /* WINED3DSIH_TEXLDL */ shader_glsl_texldl, - /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth, - /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad, - /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex, - /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3, - /* WINED3DSIH_TEXM3x3DIFF */ NULL, - /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad, - /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec, - /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex, - /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec, - /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar, - /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb, - /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb, - /* WINED3DSIH_UDIV */ shader_glsl_udiv, - /* WINED3DSIH_UGE */ shader_glsl_relop, - /* WINED3DSIH_USHR */ shader_glsl_binop, - /* WINED3DSIH_UTOF */ shader_glsl_to_float, - /* WINED3DSIH_XOR */ shader_glsl_binop, + /* WINED3DSIH_ABS */ shader_glsl_map2gl, + /* WINED3DSIH_ADD */ shader_glsl_binop, + /* WINED3DSIH_AND */ shader_glsl_binop, + /* WINED3DSIH_ATOMIC_AND */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_CMP_STORE */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_IADD */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_IMAX */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_IMIN */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_OR */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_UMAX */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_UMIN */ shader_glsl_atomic, + /* WINED3DSIH_ATOMIC_XOR */ shader_glsl_atomic, + /* WINED3DSIH_BEM */ shader_glsl_bem, + /* WINED3DSIH_BFI */ shader_glsl_bitwise_op, + /* WINED3DSIH_BFREV */ shader_glsl_map2gl, + /* WINED3DSIH_BREAK */ shader_glsl_break, + /* WINED3DSIH_BREAKC */ shader_glsl_breakc, + /* WINED3DSIH_BREAKP */ shader_glsl_conditional_op, + /* WINED3DSIH_BUFINFO */ shader_glsl_bufinfo, + /* WINED3DSIH_CALL */ shader_glsl_call, + /* WINED3DSIH_CALLNZ */ shader_glsl_callnz, + /* WINED3DSIH_CASE */ shader_glsl_case, + /* WINED3DSIH_CMP */ shader_glsl_conditional_move, + /* WINED3DSIH_CND */ shader_glsl_cnd, + /* WINED3DSIH_CONTINUE */ shader_glsl_continue, + /* WINED3DSIH_CONTINUEP */ shader_glsl_conditional_op, + /* WINED3DSIH_COUNTBITS */ shader_glsl_map2gl, + /* WINED3DSIH_CRS */ shader_glsl_cross, + /* WINED3DSIH_CUT */ shader_glsl_cut, + /* WINED3DSIH_CUT_STREAM */ shader_glsl_cut, + /* WINED3DSIH_DCL */ shader_glsl_nop, + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop, + /* WINED3DSIH_DCL_FUNCTION_BODY */ NULL, + /* WINED3DSIH_DCL_FUNCTION_TABLE */ NULL, + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ shader_glsl_nop, + /* WINED3DSIH_DCL_GS_INSTANCES */ shader_glsl_nop, + /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ shader_glsl_nop, + /* WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT */ shader_glsl_nop, + /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR */ shader_glsl_nop, + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ shader_glsl_nop, + /* WINED3DSIH_DCL_INDEX_RANGE */ shader_glsl_nop, + /* WINED3DSIH_DCL_INDEXABLE_TEMP */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_PS */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, + /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_SIV */ shader_glsl_nop, + /* WINED3DSIH_DCL_INTERFACE */ NULL, + /* WINED3DSIH_DCL_OUTPUT */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT_SIV */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop, + /* WINED3DSIH_DCL_RESOURCE_RAW */ shader_glsl_nop, + /* WINED3DSIH_DCL_RESOURCE_STRUCTURED */ shader_glsl_nop, + /* WINED3DSIH_DCL_SAMPLER */ shader_glsl_nop, + /* WINED3DSIH_DCL_STREAM */ NULL, + /* WINED3DSIH_DCL_TEMPS */ shader_glsl_nop, + /* WINED3DSIH_DCL_TESSELLATOR_DOMAIN */ shader_glsl_nop, + /* WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE */ shader_glsl_nop, + /* WINED3DSIH_DCL_TESSELLATOR_PARTITIONING */ shader_glsl_nop, + /* WINED3DSIH_DCL_TGSM_RAW */ shader_glsl_nop, + /* WINED3DSIH_DCL_TGSM_STRUCTURED */ shader_glsl_nop, + /* WINED3DSIH_DCL_THREAD_GROUP */ shader_glsl_nop, + /* WINED3DSIH_DCL_UAV_RAW */ shader_glsl_nop, + /* WINED3DSIH_DCL_UAV_STRUCTURED */ shader_glsl_nop, + /* WINED3DSIH_DCL_UAV_TYPED */ shader_glsl_nop, + /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop, + /* WINED3DSIH_DEF */ shader_glsl_nop, + /* WINED3DSIH_DEFAULT */ shader_glsl_default, + /* WINED3DSIH_DEFB */ shader_glsl_nop, + /* WINED3DSIH_DEFI */ shader_glsl_nop, + /* WINED3DSIH_DIV */ shader_glsl_binop, + /* WINED3DSIH_DP2 */ shader_glsl_dot, + /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add, + /* WINED3DSIH_DP3 */ shader_glsl_dot, + /* WINED3DSIH_DP4 */ shader_glsl_dot, + /* WINED3DSIH_DST */ shader_glsl_dst, + /* WINED3DSIH_DSX */ shader_glsl_map2gl, + /* WINED3DSIH_DSX_COARSE */ shader_glsl_map2gl, + /* WINED3DSIH_DSX_FINE */ shader_glsl_map2gl, + /* WINED3DSIH_DSY */ shader_glsl_map2gl, + /* WINED3DSIH_DSY_COARSE */ shader_glsl_map2gl, + /* WINED3DSIH_DSY_FINE */ shader_glsl_map2gl, + /* WINED3DSIH_ELSE */ shader_glsl_else, + /* WINED3DSIH_EMIT */ shader_glsl_emit, + /* WINED3DSIH_EMIT_STREAM */ shader_glsl_emit, + /* WINED3DSIH_ENDIF */ shader_glsl_end, + /* WINED3DSIH_ENDLOOP */ shader_glsl_end, + /* WINED3DSIH_ENDREP */ shader_glsl_end, + /* WINED3DSIH_ENDSWITCH */ shader_glsl_end, + /* WINED3DSIH_EQ */ shader_glsl_relop, + /* WINED3DSIH_EXP */ shader_glsl_scalar_op, + /* WINED3DSIH_EXPP */ shader_glsl_expp, + /* WINED3DSIH_F16TOF32 */ shader_glsl_float16, + /* WINED3DSIH_F32TOF16 */ shader_glsl_float16, + /* WINED3DSIH_FCALL */ NULL, + /* WINED3DSIH_FIRSTBIT_HI */ shader_glsl_map2gl, + /* WINED3DSIH_FIRSTBIT_LO */ shader_glsl_map2gl, + /* WINED3DSIH_FIRSTBIT_SHI */ shader_glsl_map2gl, + /* WINED3DSIH_FRC */ shader_glsl_map2gl, + /* WINED3DSIH_FTOI */ shader_glsl_to_int, + /* WINED3DSIH_FTOU */ shader_glsl_to_uint, + /* WINED3DSIH_GATHER4 */ shader_glsl_gather4, + /* WINED3DSIH_GATHER4_C */ shader_glsl_gather4, + /* WINED3DSIH_GATHER4_PO */ shader_glsl_gather4, + /* WINED3DSIH_GATHER4_PO_C */ shader_glsl_gather4, + /* WINED3DSIH_GE */ shader_glsl_relop, + /* WINED3DSIH_HS_CONTROL_POINT_PHASE */ shader_glsl_nop, + /* WINED3DSIH_HS_DECLS */ shader_glsl_nop, + /* WINED3DSIH_HS_FORK_PHASE */ shader_glsl_nop, + /* WINED3DSIH_HS_JOIN_PHASE */ shader_glsl_nop, + /* WINED3DSIH_IADD */ shader_glsl_binop, + /* WINED3DSIH_IBFE */ shader_glsl_bitwise_op, + /* WINED3DSIH_IEQ */ shader_glsl_relop, + /* WINED3DSIH_IF */ shader_glsl_if, + /* WINED3DSIH_IFC */ shader_glsl_ifc, + /* WINED3DSIH_IGE */ shader_glsl_relop, + /* WINED3DSIH_ILT */ shader_glsl_relop, + /* WINED3DSIH_IMAD */ shader_glsl_mad, + /* WINED3DSIH_IMAX */ shader_glsl_map2gl, + /* WINED3DSIH_IMIN */ shader_glsl_map2gl, + /* WINED3DSIH_IMM_ATOMIC_ALLOC */ shader_glsl_uav_counter, + /* WINED3DSIH_IMM_ATOMIC_AND */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_CONSUME */ shader_glsl_uav_counter, + /* WINED3DSIH_IMM_ATOMIC_EXCH */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_IADD */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_IMAX */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_IMIN */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_OR */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_UMAX */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_UMIN */ shader_glsl_atomic, + /* WINED3DSIH_IMM_ATOMIC_XOR */ shader_glsl_atomic, + /* WINED3DSIH_IMUL */ shader_glsl_mul_extended, + /* WINED3DSIH_INE */ shader_glsl_relop, + /* WINED3DSIH_INEG */ shader_glsl_unary_op, + /* WINED3DSIH_ISHL */ shader_glsl_binop, + /* WINED3DSIH_ISHR */ shader_glsl_binop, + /* WINED3DSIH_ITOF */ shader_glsl_to_float, + /* WINED3DSIH_LABEL */ shader_glsl_label, + /* WINED3DSIH_LD */ shader_glsl_ld, + /* WINED3DSIH_LD2DMS */ NULL, + /* WINED3DSIH_LD_RAW */ shader_glsl_ld_raw_structured, + /* WINED3DSIH_LD_STRUCTURED */ shader_glsl_ld_raw_structured, + /* WINED3DSIH_LD_UAV_TYPED */ shader_glsl_ld_uav, + /* WINED3DSIH_LIT */ shader_glsl_lit, + /* WINED3DSIH_LOD */ NULL, + /* WINED3DSIH_LOG */ shader_glsl_scalar_op, + /* WINED3DSIH_LOGP */ shader_glsl_scalar_op, + /* WINED3DSIH_LOOP */ shader_glsl_loop, + /* WINED3DSIH_LRP */ shader_glsl_lrp, + /* WINED3DSIH_LT */ shader_glsl_relop, + /* WINED3DSIH_M3x2 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x4 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x4 */ shader_glsl_mnxn, + /* WINED3DSIH_MAD */ shader_glsl_mad, + /* WINED3DSIH_MAX */ shader_glsl_map2gl, + /* WINED3DSIH_MIN */ shader_glsl_map2gl, + /* WINED3DSIH_MOV */ shader_glsl_mov, + /* WINED3DSIH_MOVA */ shader_glsl_mov, + /* WINED3DSIH_MOVC */ shader_glsl_conditional_move, + /* WINED3DSIH_MUL */ shader_glsl_binop, + /* WINED3DSIH_NE */ shader_glsl_relop, + /* WINED3DSIH_NOP */ shader_glsl_nop, + /* WINED3DSIH_NOT */ shader_glsl_unary_op, + /* WINED3DSIH_NRM */ shader_glsl_nrm, + /* WINED3DSIH_OR */ shader_glsl_binop, + /* WINED3DSIH_PHASE */ shader_glsl_nop, + /* WINED3DSIH_POW */ shader_glsl_pow, + /* WINED3DSIH_RCP */ shader_glsl_scalar_op, + /* WINED3DSIH_REP */ shader_glsl_rep, + /* WINED3DSIH_RESINFO */ shader_glsl_resinfo, + /* WINED3DSIH_RET */ shader_glsl_ret, + /* WINED3DSIH_RETP */ shader_glsl_conditional_op, + /* WINED3DSIH_ROUND_NE */ shader_glsl_map2gl, + /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, + /* WINED3DSIH_ROUND_PI */ shader_glsl_map2gl, + /* WINED3DSIH_ROUND_Z */ shader_glsl_map2gl, + /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, + /* WINED3DSIH_SAMPLE */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_B */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_C */ shader_glsl_sample_c, + /* WINED3DSIH_SAMPLE_C_LZ */ shader_glsl_sample_c, + /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_INFO */ NULL, + /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_POS */ NULL, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_glsl_compare, + /* WINED3DSIH_SGN */ shader_glsl_sgn, + /* WINED3DSIH_SINCOS */ shader_glsl_sincos, + /* WINED3DSIH_SLT */ shader_glsl_compare, + /* WINED3DSIH_SQRT */ shader_glsl_map2gl, + /* WINED3DSIH_STORE_RAW */ shader_glsl_store_raw_structured, + /* WINED3DSIH_STORE_STRUCTURED */ shader_glsl_store_raw_structured, + /* WINED3DSIH_STORE_UAV_TYPED */ shader_glsl_store_uav, + /* WINED3DSIH_SUB */ shader_glsl_binop, + /* WINED3DSIH_SWAPC */ NULL, + /* WINED3DSIH_SWITCH */ shader_glsl_switch, + /* WINED3DSIH_SYNC */ shader_glsl_sync, + /* WINED3DSIH_TEX */ shader_glsl_tex, + /* WINED3DSIH_TEXBEM */ shader_glsl_texbem, + /* WINED3DSIH_TEXBEML */ shader_glsl_texbem, + /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord, + /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth, + /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3, + /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex, + /* WINED3DSIH_TEXKILL */ shader_glsl_texkill, + /* WINED3DSIH_TEXLDD */ shader_glsl_texldd, + /* WINED3DSIH_TEXLDL */ shader_glsl_texldl, + /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb, + /* WINED3DSIH_UBFE */ shader_glsl_bitwise_op, + /* WINED3DSIH_UDIV */ shader_glsl_udiv, + /* WINED3DSIH_UGE */ shader_glsl_relop, + /* WINED3DSIH_ULT */ shader_glsl_relop, + /* WINED3DSIH_UMAX */ shader_glsl_map2gl, + /* WINED3DSIH_UMIN */ shader_glsl_map2gl, + /* WINED3DSIH_UMUL */ shader_glsl_mul_extended, + /* WINED3DSIH_USHR */ shader_glsl_binop, + /* WINED3DSIH_UTOF */ shader_glsl_to_float, + /* WINED3DSIH_XOR */ shader_glsl_binop, }; static void shader_glsl_handle_instruction(const struct wined3d_shader_instruction *ins) { @@ -8186,10 +10866,10 @@ static BOOL shader_glsl_has_ffp_proj_control(void *shader_priv) const struct wined3d_shader_backend_ops glsl_shader_backend = { shader_glsl_handle_instruction, + shader_glsl_precompile, shader_glsl_select, + shader_glsl_select_compute, shader_glsl_disable, - shader_glsl_select_depth_blt, - shader_glsl_deselect_depth_blt, shader_glsl_update_float_vertex_constants, shader_glsl_update_float_pixel_constants, shader_glsl_load_constants, @@ -8209,7 +10889,7 @@ static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BO static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps) { caps->xyzrhw = TRUE; - caps->emulated_flatshading = !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]; + caps->emulated_flatshading = !needs_legacy_glsl_syntax(gl_info); caps->ffp_generic_attributes = TRUE; caps->max_active_lights = MAX_ACTIVE_LIGHTS; caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; @@ -8222,7 +10902,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, | WINED3DVTXPCAPS_LOCALVIEWER | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP; caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */ - caps->max_user_clip_planes = gl_info->limits.clipplanes; + caps->max_user_clip_planes = gl_info->limits.user_clip_distances; caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE; } @@ -8290,6 +10970,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, { const struct wined3d_gl_info *gl_info = context->gl_info; BOOL normal = !!(context->stream_info.use_map & (1u << WINED3D_FFP_NORMAL)); + const BOOL legacy_clip_planes = needs_legacy_glsl_syntax(gl_info); BOOL transformed = context->stream_info.position_transformed; BOOL wasrhw = context->last_was_rhw; unsigned int i; @@ -8299,15 +10980,21 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, /* If the vertex declaration contains a transformed position attribute, * the draw uses the fixed function vertex pipeline regardless of any * vertex shader set by the application. */ - if (transformed != wasrhw) + if (transformed != wasrhw + || context->stream_info.swizzle_map != context->last_swizzle_map) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; + context->last_swizzle_map = context->stream_info.swizzle_map; + if (!use_vs(state)) { if (context->last_was_vshader) { - for (i = 0; i < gl_info->limits.clipplanes; ++i) - clipplane(context, state, STATE_CLIPPLANE(i)); + if (legacy_clip_planes) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + clipplane(context, state, STATE_CLIPPLANE(i)); + else + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; @@ -8328,9 +11015,12 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, { if (!context->last_was_vshader) { - /* Vertex shader clipping ignores the view matrix. Update all clipplanes. */ - for (i = 0; i < gl_info->limits.clipplanes; ++i) - clipplane(context, state, STATE_CLIPPLANE(i)); + /* Vertex shader clipping ignores the view matrix. Update all clip planes. */ + if (legacy_clip_planes) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + clipplane(context, state, STATE_CLIPPLANE(i)); + else + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } } @@ -8347,6 +11037,40 @@ static void glsl_vertex_pipe_vs(struct wined3d_context *context, context_apply_state(context, state, STATE_VDECL); } +static void glsl_vertex_pipe_hs(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + /* In Direct3D tessellator options (e.g. output primitive type, primitive + * winding) are defined in Hull Shaders, while in GLSL those are + * specified in Tessellation Evaluation Shaders. */ + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN; + + if (state->shader[WINED3D_SHADER_TYPE_VERTEX]) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; +} + +static void glsl_vertex_pipe_geometry_shader(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + if (state->shader[WINED3D_SHADER_TYPE_DOMAIN]) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN; + else if (state->shader[WINED3D_SHADER_TYPE_VERTEX] + && state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.shader_version.major >= 4) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; +} + +static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_GEOMETRY; + else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN]) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN; + else if (state->shader[WINED3D_SHADER_TYPE_VERTEX] + && state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.shader_version.major >= 4) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; +} + static void glsl_vertex_pipe_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -8368,10 +11092,17 @@ static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct | WINED3D_SHADER_CONST_FFP_LIGHTS | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; - for (k = 0; k < gl_info->limits.clipplanes; ++k) + if (needs_legacy_glsl_syntax(gl_info)) { - if (!isStateDirty(context, STATE_CLIPPLANE(k))) - clipplane(context, state, STATE_CLIPPLANE(k)); + for (k = 0; k < gl_info->limits.user_clip_distances; ++k) + { + if (!isStateDirty(context, STATE_CLIPPLANE(k))) + clipplane(context, state, STATE_CLIPPLANE(k)); + } + } + else + { + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } } @@ -8393,7 +11124,7 @@ static void glsl_vertex_pipe_viewport(struct wined3d_context *context, if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)) && state->render_states[WINED3D_RS_POINTSCALEENABLE]) context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; } static void glsl_vertex_pipe_texmatrix(struct wined3d_context *context, @@ -8452,50 +11183,106 @@ static void glsl_vertex_pipe_pointscale(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE; } +static void glsl_vertex_pointsprite_core(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + static unsigned int once; + + if (state->gl_primitive_type == GL_POINTS && !state->render_states[WINED3D_RS_POINTSPRITEENABLE] && !once++) + FIXME("Non-point sprite points not supported in core profile.\n"); +} + static void glsl_vertex_pipe_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX; + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; +} + +static void glsl_vertex_pipe_clip_plane(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + UINT index = state_id - STATE_CLIPPLANE(0); + + if (index >= gl_info->limits.user_clip_distances) + return; + + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE }, {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_vertex_pipe_vs }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_HULL), {STATE_SHADER(WINED3D_SHADER_TYPE_HULL), glsl_vertex_pipe_hs }, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), glsl_vertex_pipe_geometry_shader}, WINED3D_GL_EXT_NONE }, + {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), glsl_vertex_pipe_pixel_shader}, WINED3D_GL_EXT_NONE }, {STATE_MATERIAL, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_vertex_pipe_material}, WINED3D_GL_EXT_NONE }, /* Clip planes */ + {STATE_CLIPPLANE(0), {STATE_CLIPPLANE(0), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(0), {STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(1), {STATE_CLIPPLANE(1), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(1), {STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(2), {STATE_CLIPPLANE(2), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(2), {STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(3), {STATE_CLIPPLANE(3), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(3), {STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(4), {STATE_CLIPPLANE(4), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(4), {STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(5), {STATE_CLIPPLANE(5), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(5), {STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE }, + {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE }, /* Lights */ {STATE_LIGHT_TYPE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -8560,7 +11347,8 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), glsl_vertex_pipe_pointsize}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE }, - {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_LEGACY_CONTEXT }, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_vertex_pointsprite_core}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), glsl_vertex_pipe_pointscale}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -8597,8 +11385,8 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, {STATE_SAMPLER(7), {STATE_SAMPLER(7), glsl_vertex_pipe_texmatrix_np2}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_nop }, WINED3D_GL_LEGACY_CONTEXT }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_shademode}, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_shademode}, WINED3D_GLSL_130 }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_nop }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE }, }; @@ -8651,8 +11439,8 @@ static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, s | WINED3DTEXOPCAPS_LERP | WINED3DTEXOPCAPS_BUMPENVMAP | WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE; - caps->MaxTextureBlendStages = 8; - caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); + caps->MaxTextureBlendStages = MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_TEXTURES); } static DWORD glsl_fragment_pipe_get_emul_mask(const struct wined3d_gl_info *gl_info) @@ -8784,35 +11572,47 @@ static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *cont context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS; } +static void glsl_fragment_pipe_alpha_test_func(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLint func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); + float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f; + + if (func) + { + gl_info->gl_ops.gl.p_glAlphaFunc(func, ref); + checkGLcall("glAlphaFunc"); + } +} + +static void glsl_fragment_pipe_core_alpha_test(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; +} + static void glsl_fragment_pipe_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - int glParm; - float ref; - - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); if (state->render_states[WINED3D_RS_ALPHATESTENABLE]) { gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); - checkGLcall("glEnable GL_ALPHA_TEST"); + checkGLcall("glEnable(GL_ALPHA_TEST)"); } else { gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - checkGLcall("glDisable GL_ALPHA_TEST"); - return; + checkGLcall("glDisable(GL_ALPHA_TEST)"); } +} - ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f; - glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); - - if (glParm) - { - gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref); - checkGLcall("glAlphaFunc"); - } +static void glsl_fragment_pipe_core_alpha_test_ref(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_ALPHA_TEST; } static void glsl_fragment_pipe_color_key(struct wined3d_context *context, @@ -8824,7 +11624,7 @@ static void glsl_fragment_pipe_color_key(struct wined3d_context *context, static void glsl_fragment_pipe_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL; + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; } static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = @@ -8905,9 +11705,12 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), glsl_fragment_pipe_alpha_test_func }, WINED3D_GL_LEGACY_CONTEXT}, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), glsl_fragment_pipe_alpha_test }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), NULL }, WINED3D_GL_LEGACY_CONTEXT}, + {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), glsl_fragment_pipe_core_alpha_test_ref }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), glsl_fragment_pipe_alpha_test }, WINED3D_GL_LEGACY_CONTEXT}, + {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), glsl_fragment_pipe_core_alpha_test }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_COLOR_KEY, { STATE_COLOR_KEY, glsl_fragment_pipe_color_key }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, @@ -8920,6 +11723,7 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, ARB_POINT_SPRITE }, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, WINED3D_GL_VERSION_2_0}, {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, @@ -8938,8 +11742,8 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_LEGACY_CONTEXT}, - {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GLSL_130 }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE }, }; diff --git a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c index 51fc9bc0d81..9449a52d35c 100644 --- a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -642,10 +642,10 @@ static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3 static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_color color; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); - GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0])); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); + GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &color.r)); } /* Context activation is done by the caller. */ diff --git a/reactos/dll/directx/wine/wined3d/palette.c b/reactos/dll/directx/wine/wined3d/palette.c index 7fcc126d7f4..218d83f58a9 100644 --- a/reactos/dll/directx/wine/wined3d/palette.c +++ b/reactos/dll/directx/wine/wined3d/palette.c @@ -32,6 +32,11 @@ ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette) return refcount; } +static void wined3d_palette_destroy_object(void *object) +{ + HeapFree(GetProcessHeap(), 0, object); +} + ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette) { ULONG refcount = InterlockedDecrement(&palette->ref); @@ -39,7 +44,7 @@ ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette) TRACE("%p decreasing refcount to %u.\n", palette, refcount); if (!refcount) - HeapFree(GetProcessHeap(), 0, palette); + wined3d_cs_destroy_object(palette->device->cs, wined3d_palette_destroy_object, palette); return refcount; } diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index bc95a7dbda4..3060432ff42 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -23,6 +23,47 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); +static void wined3d_query_init(struct wined3d_query *query, struct wined3d_device *device, + enum wined3d_query_type type, const void *data, DWORD data_size, + const struct wined3d_query_ops *query_ops, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + query->ref = 1; + query->parent = parent; + query->parent_ops = parent_ops; + query->device = device; + query->state = QUERY_CREATED; + query->type = type; + query->data = data; + query->data_size = data_size; + query->query_ops = query_ops; + list_init(&query->poll_list_entry); +} + +static struct wined3d_event_query *wined3d_event_query_from_query(struct wined3d_query *query) +{ + return CONTAINING_RECORD(query, struct wined3d_event_query, query); +} + +static struct wined3d_occlusion_query *wined3d_occlusion_query_from_query(struct wined3d_query *query) +{ + return CONTAINING_RECORD(query, struct wined3d_occlusion_query, query); +} + +static struct wined3d_timestamp_query *wined3d_timestamp_query_from_query(struct wined3d_query *query) +{ + return CONTAINING_RECORD(query, struct wined3d_timestamp_query, query); +} + +static struct wined3d_so_statistics_query *wined3d_so_statistics_query_from_query(struct wined3d_query *query) +{ + return CONTAINING_RECORD(query, struct wined3d_so_statistics_query, query); +} + +static struct wined3d_pipeline_statistics_query *wined3d_pipeline_statistics_query_from_query(struct wined3d_query *query) +{ + return CONTAINING_RECORD(query, struct wined3d_pipeline_statistics_query, query); +} + BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) { return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE]; @@ -35,33 +76,36 @@ void wined3d_event_query_destroy(struct wined3d_event_query *query) } static enum wined3d_event_query_result wined3d_event_query_test(const struct wined3d_event_query *query, - const struct wined3d_device *device) + const struct wined3d_device *device, DWORD flags) { - struct wined3d_context *context; const struct wined3d_gl_info *gl_info; enum wined3d_event_query_result ret; + struct wined3d_context *context; BOOL fence_result; - TRACE("(%p) : device %p\n", query, device); + TRACE("query %p, device %p, flags %#x.\n", query, device, flags); if (!query->context) { - TRACE("Query not started\n"); + TRACE("Query not started.\n"); return WINED3D_EVENT_QUERY_NOT_STARTED; } - if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) + if (!(context = context_reacquire(device, query->context))) { - WARN("Event query tested from wrong thread\n"); - return WINED3D_EVENT_QUERY_WRONG_THREAD; + if (!query->context->gl_info->supported[ARB_SYNC]) + { + WARN("Event query tested from wrong thread.\n"); + return WINED3D_EVENT_QUERY_WRONG_THREAD; + } + context = context_acquire(device, NULL, 0); } - - context = context_acquire(device, query->context->current_rt); gl_info = context->gl_info; if (gl_info->supported[ARB_SYNC]) { - GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0)); + GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, + (flags & WINED3DGETDATA_FLUSH) ? GL_SYNC_FLUSH_COMMANDS_BIT : 0, 0)); checkGLcall("glClientWaitSync"); switch (gl_ret) @@ -108,29 +152,32 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query, const struct wined3d_device *device) { - struct wined3d_context *context; const struct wined3d_gl_info *gl_info; enum wined3d_event_query_result ret; + struct wined3d_context *context; TRACE("query %p, device %p.\n", query, device); if (!query->context) { - TRACE("Query not started\n"); + TRACE("Query not started.\n"); return WINED3D_EVENT_QUERY_NOT_STARTED; } gl_info = query->context->gl_info; - if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC]) + if (!(context = context_reacquire(device, query->context))) { /* A glFinish does not reliably wait for draws in other contexts. The caller has * to find its own way to cope with the thread switch */ - WARN("Event query finished from wrong thread\n"); - return WINED3D_EVENT_QUERY_WRONG_THREAD; + if (!gl_info->supported[ARB_SYNC]) + { + WARN("Event query finished from wrong thread.\n"); + return WINED3D_EVENT_QUERY_WRONG_THREAD; + } + context = context_acquire(device, NULL, 0); } - - context = context_acquire(device, query->context->current_rt); + gl_info = context->gl_info; if (gl_info->supported[ARB_SYNC]) { @@ -177,29 +224,17 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_ void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) { + struct wined3d_context *context = NULL; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - if (query->context) - { - if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) - { - context_free_event_query(query); - context = context_acquire(device, NULL); - context_alloc_event_query(context, query); - } - else - { - context = context_acquire(device, query->context->current_rt); - } - } - else - { - context = context_acquire(device, NULL); - context_alloc_event_query(context, query); - } + if (query->context && !(context = context_reacquire(device, query->context)) + && !query->context->gl_info->supported[ARB_SYNC]) + context_free_event_query(query); + if (!context) + context = context_acquire(device, NULL, 0); gl_info = context->gl_info; + if (!query->context) + context_alloc_event_query(context, query); if (gl_info->supported[ARB_SYNC]) { @@ -231,38 +266,73 @@ ULONG CDECL wined3d_query_incref(struct wined3d_query *query) return refcount; } -#if defined(STAGING_CSMT) -void wined3d_query_destroy(struct wined3d_query *query) +static void wined3d_query_destroy_object(void *object) { + struct wined3d_query *query = object; + + if (!list_empty(&query->poll_list_entry)) + list_remove(&query->poll_list_entry); + /* Queries are specific to the GL context that created them. Not * deleting the query will obviously leak it, but that's still better * than potentially deleting a different query with the same id in this * context, and (still) leaking the actual query. */ if (query->type == WINED3D_QUERY_TYPE_EVENT) { - struct wined3d_event_query *event_query = query->extendedData; - if (event_query) wined3d_event_query_destroy(event_query); + wined3d_event_query_destroy(wined3d_event_query_from_query(query)); } else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) { - struct wined3d_occlusion_query *oq = query->extendedData; + struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); - if (oq->context) context_free_occlusion_query(oq); - HeapFree(GetProcessHeap(), 0, query->extendedData); + if (oq->context) + context_free_occlusion_query(oq); + HeapFree(GetProcessHeap(), 0, oq); } else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) { - struct wined3d_timestamp_query *tq = query->extendedData; + struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); if (tq->context) context_free_timestamp_query(tq); - HeapFree(GetProcessHeap(), 0, query->extendedData); + HeapFree(GetProcessHeap(), 0, tq); + } + else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT + || query->type == WINED3D_QUERY_TYPE_TIMESTAMP_FREQ) + { + HeapFree(GetProcessHeap(), 0, query); + } + else if (query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0 + || query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1 + || query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2 + || query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3) + { + struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); + if (pq->context) + context_free_so_statistics_query(pq); + HeapFree(GetProcessHeap(), 0, pq); + } + else if (query->type == WINED3D_QUERY_TYPE_SO_STATISTICS) + { + HeapFree(GetProcessHeap(), 0, query); + } + else if (query->type == WINED3D_QUERY_TYPE_SO_OVERFLOW) + { + HeapFree(GetProcessHeap(), 0, query); + } + else if (query->type == WINED3D_QUERY_TYPE_PIPELINE_STATISTICS) + { + struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); + if (pq->context) + context_free_pipeline_statistics_query(pq); + HeapFree(GetProcessHeap(), 0, query); + } + else + { + ERR("Query %p has invalid type %#x.\n", query, query->type); } - - HeapFree(GetProcessHeap(), 0, query); } -#endif /* STAGING_CSMT */ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) { ULONG refcount = InterlockedDecrement(&query->ref); @@ -270,38 +340,10 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) TRACE("%p decreasing refcount to %u.\n", query, refcount); if (!refcount) -#if defined(STAGING_CSMT) - wined3d_cs_emit_query_destroy(query->device->cs, query); -#else /* STAGING_CSMT */ { - /* Queries are specific to the GL context that created them. Not - * deleting the query will obviously leak it, but that's still better - * than potentially deleting a different query with the same id in this - * context, and (still) leaking the actual query. */ - if (query->type == WINED3D_QUERY_TYPE_EVENT) - { - struct wined3d_event_query *event_query = query->extendedData; - if (event_query) wined3d_event_query_destroy(event_query); - } - else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) - { - struct wined3d_occlusion_query *oq = query->extendedData; - - if (oq->context) context_free_occlusion_query(oq); - HeapFree(GetProcessHeap(), 0, query->extendedData); - } - else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) - { - struct wined3d_timestamp_query *tq = query->extendedData; - - if (tq->context) - context_free_timestamp_query(tq); - HeapFree(GetProcessHeap(), 0, query->extendedData); - } - - HeapFree(GetProcessHeap(), 0, query); + query->parent_ops->wined3d_object_destroyed(query->parent); + wined3d_cs_destroy_object(query->device->cs, wined3d_query_destroy_object, query); } -#endif /* STAGING_CSMT */ return refcount; } @@ -312,7 +354,37 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, TRACE("query %p, data %p, data_size %u, flags %#x.\n", query, data, data_size, flags); - return query->query_ops->query_get_data(query, data, data_size, flags); + if (flags) + WARN("Ignoring flags %#x.\n", flags); + + if (query->state == QUERY_BUILDING) + { + WARN("Query is building, returning S_FALSE.\n"); + return S_FALSE; + } + + if (query->state == QUERY_CREATED) + { + WARN("Query wasn't started yet.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (!query->device->cs->thread) + { + if (!query->query_ops->query_poll(query, flags)) + return S_FALSE; + } + else if (query->counter_main != query->counter_retrieved) + { + if (flags & WINED3DGETDATA_FLUSH) + wined3d_cs_emit_flush(query->device->cs); + return S_FALSE; + } + + if (data) + memcpy(data, query->data, min(data_size, query->data_size)); + + return S_OK; } UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) @@ -326,9 +398,8 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) { TRACE("query %p, flags %#x.\n", query, flags); -#if defined(STAGING_CSMT) if (flags & WINED3DISSUE_END) - query->counter_main++; + ++query->counter_main; wined3d_cs_emit_query_issue(query->device->cs, query, flags); @@ -338,110 +409,25 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) query->state = QUERY_SIGNALLED; return WINED3D_OK; -#else /* STAGING_CSMT */ - return query->query_ops->query_issue(query, flags); -#endif /* STAGING_CSMT */ } -static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) +static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD flags) { - memcpy(out, result, min(out_size, result_size)); -} - -static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) -{ -#if defined(STAGING_CSMT) + struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_occlusion_query *oq = query->extendedData; - GLuint samples; -#else /* STAGING_CSMT */ - struct wined3d_occlusion_query *oq = query->extendedData; - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; GLuint available; - GLuint samples; - HRESULT res; - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); + TRACE("query %p, flags %#x.\n", query, flags); - if (!oq->context) - query->state = QUERY_CREATED; -#endif /* STAGING_CSMT */ - - if (query->state == QUERY_CREATED) - { - /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ - TRACE("Query wasn't yet started, returning S_OK\n"); - samples = 0; - fill_query_data(data, size, &samples, sizeof(samples)); - return S_OK; - } - -#if defined(STAGING_CSMT) - TRACE("(%p) : type D3DQUERY_OCCLUSION, data %p, size %#x, flags %#x.\n", query, data, size, flags); - -#endif /* STAGING_CSMT */ - if (query->state == QUERY_BUILDING) - { - /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ - TRACE("Query is building, returning S_FALSE\n"); - return S_FALSE; - } - - if (!gl_info->supported[ARB_OCCLUSION_QUERY]) - { - WARN("%p Occlusion queries not supported. Returning 1.\n", query); - samples = 1; - fill_query_data(data, size, &samples, sizeof(samples)); - return S_OK; - } - -#if defined(STAGING_CSMT) - if (!wined3d_settings.cs_multithreaded) - { - if (!query->query_ops->query_poll(query)) - return S_FALSE; - } - else if (query->counter_main != query->counter_retrieved) - { - return S_FALSE; - } - - if (data) - fill_query_data(data, size, &oq->samples, sizeof(oq->samples)); - - return S_OK; -} - -static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query) -{ - struct wined3d_occlusion_query *oq = query->extendedData; - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; - GLuint available; - GLuint samples; - BOOL ret; - - if (oq->context->tid != GetCurrentThreadId()) + if (!(context = context_reacquire(device, oq->context))) { FIXME("%p Wrong thread, returning 1.\n", query); oq->samples = 1; return TRUE; -#else /* STAGING_CSMT */ - if (oq->context->tid != GetCurrentThreadId()) - { - FIXME("%p Wrong thread, returning 1.\n", query); - samples = 1; - fill_query_data(data, size, &samples, sizeof(samples)); - return S_OK; -#endif /* STAGING_CSMT */ } - - context = context_acquire(query->device, oq->context->current_rt); + gl_info = context->gl_info; GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); @@ -449,145 +435,59 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query) if (available) { -#if defined(STAGING_CSMT) - GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); - checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); - TRACE("Returning %d samples.\n", samples); - oq->samples = samples; - ret = TRUE; - } - else - { - ret = FALSE; + if (gl_info->supported[ARB_TIMER_QUERY]) + { + GLuint64 result; + GL_EXTCALL(glGetQueryObjectui64v(oq->id, GL_QUERY_RESULT, &result)); + checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); + oq->samples = result; + } + else + { + GLuint result; + GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &result)); + checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); + oq->samples = result; + } + TRACE("Returning 0x%s samples.\n", wine_dbgstr_longlong(oq->samples)); } context_release(context); - return ret; + return available; } -static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query) +static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query, DWORD flags) { - struct wined3d_event_query *event_query = query->extendedData; + struct wined3d_event_query *event_query = wined3d_event_query_from_query(query); enum wined3d_event_query_result ret; - ret = wined3d_event_query_test(event_query, query->device); - switch(ret) + TRACE("query %p, flags %#x.\n", query, flags); + + ret = wined3d_event_query_test(event_query, query->device, flags); + switch (ret) { case WINED3D_EVENT_QUERY_OK: case WINED3D_EVENT_QUERY_NOT_STARTED: - return TRUE; + return event_query->signalled = TRUE; case WINED3D_EVENT_QUERY_WAITING: - return FALSE; + return event_query->signalled = FALSE; case WINED3D_EVENT_QUERY_WRONG_THREAD: FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); - return TRUE; + return event_query->signalled = TRUE; case WINED3D_EVENT_QUERY_ERROR: - ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); - return TRUE; + ERR("The GL event query failed.\n"); + return event_query->signalled = TRUE; default: - ERR("Unexpected wined3d_event_query_test result %u\n", ret); - return TRUE; + ERR("Unexpected wined3d_event_query_test result %#x.\n", ret); + return event_query->signalled = TRUE; } } -static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, - void *pData, DWORD dwSize, DWORD flags) -{ - struct wined3d_event_query *event_query = query->extendedData; - BOOL *data = pData; - enum wined3d_event_query_result ret; - - TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags); - - if (!pData || !dwSize) return S_OK; - if (!event_query) - { - WARN("Event query not supported by GL, reporting GPU idle.\n"); - *data = TRUE; - return S_OK; - } - - if (!wined3d_settings.cs_multithreaded) - ret = query->query_ops->query_poll(query); - else if (query->counter_main != query->counter_retrieved) - ret = FALSE; - else - ret = TRUE; - - if (data) - fill_query_data(data, dwSize, &ret, sizeof(ret)); -#else /* STAGING_CSMT */ - if (size) - { - GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); - checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); - TRACE("Returning %d samples.\n", samples); - fill_query_data(data, size, &samples, sizeof(samples)); - } - res = S_OK; - } - else - { - res = S_FALSE; - } - - context_release(context); - - return res; -} - -static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) -{ - struct wined3d_event_query *event_query = query->extendedData; - BOOL signaled; - enum wined3d_event_query_result ret; - - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); - - if (!data || !size) return S_OK; - if (!event_query) - { - WARN("Event query not supported by GL, reporting GPU idle.\n"); - signaled = TRUE; - fill_query_data(data, size, &signaled, sizeof(signaled)); - return S_OK; - } - - ret = wined3d_event_query_test(event_query, query->device); - switch(ret) - { - case WINED3D_EVENT_QUERY_OK: - case WINED3D_EVENT_QUERY_NOT_STARTED: - signaled = TRUE; - fill_query_data(data, size, &signaled, sizeof(signaled)); - break; - - case WINED3D_EVENT_QUERY_WAITING: - signaled = FALSE; - fill_query_data(data, size, &signaled, sizeof(signaled)); - break; - - case WINED3D_EVENT_QUERY_WRONG_THREAD: - FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); - signaled = TRUE; - fill_query_data(data, size, &signaled, sizeof(signaled)); - break; - - case WINED3D_EVENT_QUERY_ERROR: - ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); - return WINED3DERR_INVALIDCALL; - } -#endif /* STAGING_CSMT */ - - return S_OK; -} - void * CDECL wined3d_query_get_parent(const struct wined3d_query *query) { TRACE("query %p.\n", query); @@ -602,254 +502,113 @@ enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query return query->type; } -#if defined(STAGING_CSMT) static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -#else /* STAGING_CSMT */ -static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -#endif /* STAGING_CSMT */ { TRACE("query %p, flags %#x.\n", query, flags); - TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", query, flags); if (flags & WINED3DISSUE_END) { - struct wined3d_event_query *event_query = query->extendedData; - - /* Faked event query support */ -#if defined(STAGING_CSMT) - if (!event_query) return FALSE; + struct wined3d_event_query *event_query = wined3d_event_query_from_query(query); wined3d_event_query_issue(event_query, query->device); return TRUE; } else if (flags & WINED3DISSUE_BEGIN) { - /* Started implicitly at device creation */ + /* Started implicitly at query creation. */ ERR("Event query issued with START flag - what to do?\n"); } + return FALSE; } static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - BOOL poll = FALSE; -#else /* STAGING_CSMT */ - if (!event_query) return WINED3D_OK; - - wined3d_event_query_issue(event_query, query->device); - } - else if (flags & WINED3DISSUE_BEGIN) - { - /* Started implicitly at device creation */ - ERR("Event query issued with START flag - what to do?\n"); - } - - if (flags & WINED3DISSUE_BEGIN) - query->state = QUERY_BUILDING; - else - query->state = QUERY_SIGNALLED; - - return WINED3D_OK; -} - -static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) -{ - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -#endif /* STAGING_CSMT */ - - TRACE("query %p, flags %#x.\n", query, flags); - - if (gl_info->supported[ARB_OCCLUSION_QUERY]) - { - struct wined3d_occlusion_query *oq = query->extendedData; - struct wined3d_context *context; - - /* This is allowed according to msdn and our tests. Reset the query and restart */ - if (flags & WINED3DISSUE_BEGIN) - { -#if defined(STAGING_CSMT) - if (oq->started) -#else /* STAGING_CSMT */ - if (query->state == QUERY_BUILDING) -#endif /* STAGING_CSMT */ - { - if (oq->context->tid != GetCurrentThreadId()) - { - FIXME("Wrong thread, can't restart query.\n"); - - context_free_occlusion_query(oq); - context = context_acquire(query->device, NULL); - context_alloc_occlusion_query(context, oq); - } - else - { - context = context_acquire(query->device, oq->context->current_rt); - - GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); - checkGLcall("glEndQuery()"); - } - } - else - { - if (oq->context) context_free_occlusion_query(oq); - context = context_acquire(query->device, NULL); - context_alloc_occlusion_query(context, oq); - } - - GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id)); - checkGLcall("glBeginQuery()"); - - context_release(context); -#if defined(STAGING_CSMT) - oq->started = TRUE; -#endif /* STAGING_CSMT */ - } - if (flags & WINED3DISSUE_END) - { - /* Msdn says _END on a non-building occlusion query returns an error, but - * our tests show that it returns OK. But OpenGL doesn't like it, so avoid - * generating an error - */ -#if defined(STAGING_CSMT) - if (oq->started) -#else /* STAGING_CSMT */ - if (query->state == QUERY_BUILDING) -#endif /* STAGING_CSMT */ - { - if (oq->context->tid != GetCurrentThreadId()) - { - FIXME("Wrong thread, can't end query.\n"); - } - else - { - context = context_acquire(query->device, oq->context->current_rt); - - GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); - checkGLcall("glEndQuery()"); - - context_release(context); -#if defined(STAGING_CSMT) - poll = TRUE; - } - } - oq->started = FALSE; -#else /* STAGING_CSMT */ - } - } -#endif /* STAGING_CSMT */ - } - } - else - { - FIXME("%p Occlusion queries not supported.\n", query); - } - -#if defined(STAGING_CSMT) - return poll; -} - -static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) -{ - struct wined3d_timestamp_query *tq = query->extendedData; - - TRACE("(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.\n", query, data, size, flags); - - if (query->state == QUERY_CREATED) - { - UINT64 zero = 0; - /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ - TRACE("Query wasn't yet started, returning S_OK.\n"); - if (data) - fill_query_data(data, size, &zero, sizeof(zero)); - return S_OK; - } - - if (!wined3d_settings.cs_multithreaded) - { - if (!query->query_ops->query_poll(query)) - return S_FALSE; - } - else if (query->counter_main != query->counter_retrieved) - { - return S_FALSE; - } - - if (data) - fill_query_data(data, size, &tq->timestamp, sizeof(tq->timestamp)); - - return S_OK; -} - -static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) -{ - struct wined3d_timestamp_query *tq = query->extendedData; + struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; - GLuint available; - GLuint64 timestamp; - BOOL ret; + BOOL poll = FALSE; - if (!gl_info->supported[ARB_TIMER_QUERY]) + TRACE("query %p, flags %#x.\n", query, flags); + + /* This is allowed according to MSDN and our tests. Reset the query and + * restart. */ + if (flags & WINED3DISSUE_BEGIN) { - TRACE("Faking timestamp.\n"); - QueryPerformanceCounter((LARGE_INTEGER *)&tq->timestamp); - return TRUE; + if (oq->started) + { + if ((context = context_reacquire(device, oq->context))) + { + GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); + checkGLcall("glEndQuery()"); + } + else + { + FIXME("Wrong thread, can't restart query.\n"); + context_free_occlusion_query(oq); + context = context_acquire(device, NULL, 0); + context_alloc_occlusion_query(context, oq); + } + } + else + { + if (oq->context) + context_free_occlusion_query(oq); + context = context_acquire(device, NULL, 0); + context_alloc_occlusion_query(context, oq); + } + + GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id)); + checkGLcall("glBeginQuery()"); + + context_release(context); + oq->started = TRUE; + } + if (flags & WINED3DISSUE_END) + { + /* MSDN says END on a non-building occlusion query returns an error, + * but our tests show that it returns OK. But OpenGL doesn't like it, + * so avoid generating an error. */ + if (oq->started) + { + if ((context = context_reacquire(device, oq->context))) + { + GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); + checkGLcall("glEndQuery()"); + + context_release(context); + poll = TRUE; + } + else + { + FIXME("Wrong thread, can't end query.\n"); + } + } + oq->started = FALSE; } - if (tq->context->tid != GetCurrentThreadId()) + return poll; +} + +static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + GLuint64 timestamp; + GLuint available; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (!(context = context_reacquire(device, tq->context))) { FIXME("%p Wrong thread, returning 1.\n", query); tq->timestamp = 1; return TRUE; -#else /* STAGING_CSMT */ - if (flags & WINED3DISSUE_BEGIN) - query->state = QUERY_BUILDING; - else - query->state = QUERY_SIGNALLED; - - return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ -} - -static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) -{ - struct wined3d_timestamp_query *tq = query->extendedData; - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; - GLuint available; - GLuint64 timestamp; - HRESULT res; - - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); - - if (!tq->context) - query->state = QUERY_CREATED; - - if (query->state == QUERY_CREATED) - { - /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ - TRACE("Query wasn't yet started, returning S_OK.\n"); - timestamp = 0; - fill_query_data(data, size, ×tamp, sizeof(timestamp)); - return S_OK; } - - if (tq->context->tid != GetCurrentThreadId()) - { - FIXME("%p Wrong thread, returning 1.\n", query); - timestamp = 1; - fill_query_data(data, size, ×tamp, sizeof(timestamp)); - return S_OK; -#endif /* STAGING_CSMT */ - } - - context = context_acquire(query->device, tq->context->current_rt); + gl_info = context->gl_info; GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); @@ -857,334 +616,526 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, if (available) { -#if defined(STAGING_CSMT) GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); tq->timestamp = timestamp; - ret = TRUE; - } - else - { - ret = FALSE; } context_release(context); - return ret; + return available; } static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -#else /* STAGING_CSMT */ - if (size) - { - GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); - checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); - TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); - fill_query_data(data, size, ×tamp, sizeof(timestamp)); - } - res = S_OK; - } - else - { - res = S_FALSE; - } - - context_release(context); - - return res; -} - -static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -#endif /* STAGING_CSMT */ { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; TRACE("query %p, flags %#x.\n", query, flags); - if (gl_info->supported[ARB_TIMER_QUERY]) + if (flags & WINED3DISSUE_BEGIN) { - struct wined3d_timestamp_query *tq = query->extendedData; - struct wined3d_context *context; - - if (flags & WINED3DISSUE_BEGIN) - { - WARN("Ignoring WINED3DISSUE_BEGIN with a TIMESTAMP query.\n"); - } - if (flags & WINED3DISSUE_END) - { - if (tq->context) - context_free_timestamp_query(tq); - context = context_acquire(query->device, NULL); - context_alloc_timestamp_query(context, tq); - GL_EXTCALL(glQueryCounter(tq->id, GL_TIMESTAMP)); - checkGLcall("glQueryCounter()"); - context_release(context); - } + WARN("Ignoring WINED3DISSUE_BEGIN with a TIMESTAMP query.\n"); } - else - { - ERR("Timestamp queries not supported.\n"); - } - if (flags & WINED3DISSUE_END) -#if defined(STAGING_CSMT) + { + if (tq->context) + context_free_timestamp_query(tq); + context = context_acquire(query->device, NULL, 0); + gl_info = context->gl_info; + context_alloc_timestamp_query(context, tq); + GL_EXTCALL(glQueryCounter(tq->id, GL_TIMESTAMP)); + checkGLcall("glQueryCounter()"); + context_release(context); + return TRUE; + } + return FALSE; } -static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) +static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query, DWORD flags) { - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); - if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) - { - static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; + TRACE("query %p, flags %#x.\n", query, flags); - if (query->state == QUERY_BUILDING) - { - TRACE("Query is building, returning S_FALSE.\n"); - return S_FALSE; -#else /* STAGING_CSMT */ - query->state = QUERY_SIGNALLED; - - return WINED3D_OK; -} - -static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) -{ - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); - - if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) - { - static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; - - if (query->state == QUERY_BUILDING) - { - TRACE("Query is building, returning S_FALSE.\n"); - return S_FALSE; -#endif /* STAGING_CSMT */ - } - - fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data)); - } - else - { - static const UINT64 freq = 1000 * 1000 * 1000; - - fill_query_data(data, size, &freq, sizeof(freq)); - } - return S_OK; -} - -#if defined(STAGING_CSMT) -static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query) -{ return TRUE; } static BOOL wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) { TRACE("query %p, flags %#x.\n", query, flags); + return FALSE; } +static BOOL wined3d_so_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); + struct wined3d_device *device = query->device; + GLuint written_available, generated_available; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (!(context = context_reacquire(device, pq->context))) + { + FIXME("%p Wrong thread, returning 0 primitives.\n", query); + memset(&pq->statistics, 0, sizeof(pq->statistics)); + return TRUE; + } + gl_info = context->gl_info; + + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.written, + GL_QUERY_RESULT_AVAILABLE, &written_available)); + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.generated, + GL_QUERY_RESULT_AVAILABLE, &generated_available)); + TRACE("Available %#x, %#x.\n", written_available, generated_available); + + if (written_available && generated_available) + { + if (gl_info->supported[ARB_TIMER_QUERY]) + { + GLuint64 result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.written, GL_QUERY_RESULT, &result)); + pq->statistics.primitives_written = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.generated, GL_QUERY_RESULT, &result)); + pq->statistics.primitives_generated = result; + } + else + { + GLuint result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.written, GL_QUERY_RESULT, &result)); + pq->statistics.primitives_written = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.generated, GL_QUERY_RESULT, &result)); + pq->statistics.primitives_generated = result; + } + TRACE("Returning %s, %s primitives.\n", + wine_dbgstr_longlong(pq->statistics.primitives_written), + wine_dbgstr_longlong(pq->statistics.primitives_generated)); + } + + checkGLcall("poll SO statistics query"); + context_release(context); + + return written_available && generated_available; +} + +static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query); + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_context *context; + BOOL poll = FALSE; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (flags & WINED3DISSUE_BEGIN) + { + if (pq->started) + { + if ((context = context_reacquire(device, pq->context))) + { + GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, pq->stream_idx)); + GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, pq->stream_idx)); + } + else + { + FIXME("Wrong thread, can't restart query.\n"); + context_free_so_statistics_query(pq); + context = context_acquire(device, NULL, 0); + context_alloc_so_statistics_query(context, pq); + } + } + else + { + if (pq->context) + context_free_so_statistics_query(pq); + context = context_acquire(device, NULL, 0); + context_alloc_so_statistics_query(context, pq); + } + + GL_EXTCALL(glBeginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, + pq->stream_idx, pq->u.query.written)); + GL_EXTCALL(glBeginQueryIndexed(GL_PRIMITIVES_GENERATED, + pq->stream_idx, pq->u.query.generated)); + checkGLcall("begin query"); + + context_release(context); + pq->started = TRUE; + } + if (flags & WINED3DISSUE_END) + { + if (pq->started) + { + if ((context = context_reacquire(device, pq->context))) + { + GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, pq->stream_idx)); + GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, pq->stream_idx)); + checkGLcall("end query"); + + context_release(context); + poll = TRUE; + } + else + { + FIXME("Wrong thread, can't end query.\n"); + } + } + pq->started = FALSE; + } + + return poll; +} + +static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + TRACE("query %p, flags %#x.\n", query, flags); + + return TRUE; +} + +static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + FIXME("query %p, flags %#x.\n", query, flags); + + return FALSE; +} + +static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + TRACE("query %p, flags %#x.\n", query, flags); + + return TRUE; +} + +static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + FIXME("query %p, flags %#x.\n", query, flags); + + return FALSE; +} + +static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, DWORD flags) +{ + struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + GLuint available; + int i; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (!(context = context_reacquire(device, pq->context))) + { + FIXME("%p Wrong thread, returning 0 primitives.\n", query); + memset(&pq->statistics, 0, sizeof(pq->statistics)); + return TRUE; + } + gl_info = context->gl_info; + + for (i = 0; i < ARRAY_SIZE(pq->u.id); i++) + { + GL_EXTCALL(glGetQueryObjectuiv(pq->u.id[i], GL_QUERY_RESULT_AVAILABLE, &available)); + if (!available) goto done; + } + + if (gl_info->supported[ARB_TIMER_QUERY]) + { + GLuint64 result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.vertices, GL_QUERY_RESULT, &result)); + pq->statistics.ia_vertices = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.primitives, GL_QUERY_RESULT, &result)); + pq->statistics.ia_primitives = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.vertex_shader, GL_QUERY_RESULT, &result)); + pq->statistics.vs_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.tess_control_shader, GL_QUERY_RESULT, &result)); + pq->statistics.hs_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.tess_eval_shader, GL_QUERY_RESULT, &result)); + pq->statistics.ds_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.geometry_shader, GL_QUERY_RESULT, &result)); + pq->statistics.gs_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.geometry_primitives, GL_QUERY_RESULT, &result)); + pq->statistics.gs_primitives = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.fragment_shader, GL_QUERY_RESULT, &result)); + pq->statistics.ps_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.compute_shader, GL_QUERY_RESULT, &result)); + pq->statistics.cs_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.clipping_input, GL_QUERY_RESULT, &result)); + pq->statistics.c_invocations = result; + GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.clipping_output, GL_QUERY_RESULT, &result)); + pq->statistics.c_primitives = result; + } + else + { + GLuint result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.vertices, GL_QUERY_RESULT, &result)); + pq->statistics.ia_vertices = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.primitives, GL_QUERY_RESULT, &result)); + pq->statistics.ia_primitives = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.vertex_shader, GL_QUERY_RESULT, &result)); + pq->statistics.vs_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.tess_control_shader, GL_QUERY_RESULT, &result)); + pq->statistics.hs_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.tess_eval_shader, GL_QUERY_RESULT, &result)); + pq->statistics.ds_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.geometry_shader, GL_QUERY_RESULT, &result)); + pq->statistics.gs_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.geometry_primitives, GL_QUERY_RESULT, &result)); + pq->statistics.gs_primitives = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.fragment_shader, GL_QUERY_RESULT, &result)); + pq->statistics.ps_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.compute_shader, GL_QUERY_RESULT, &result)); + pq->statistics.cs_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.clipping_input, GL_QUERY_RESULT, &result)); + pq->statistics.c_invocations = result; + GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.clipping_output, GL_QUERY_RESULT, &result)); + pq->statistics.c_primitives = result; + } + +done: + checkGLcall("poll pipeline statistics query"); + context_release(context); + return available; +} + +static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD flags) +{ + struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query); + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_context *context; + BOOL poll = FALSE; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (flags & WINED3DISSUE_BEGIN) + { + if (pq->started) + { + if ((context = context_reacquire(device, pq->context))) + { + GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB)); + GL_EXTCALL(glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS)); + GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB)); + GL_EXTCALL(glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB)); + } + else + { + FIXME("Wrong thread, can't restart query.\n"); + context_free_pipeline_statistics_query(pq); + context = context_acquire(device, NULL, 0); + context_alloc_pipeline_statistics_query(context, pq); + } + } + else + { + if (pq->context) + context_free_pipeline_statistics_query(pq); + context = context_acquire(device, NULL, 0); + context_alloc_pipeline_statistics_query(context, pq); + } + + GL_EXTCALL(glBeginQuery(GL_VERTICES_SUBMITTED_ARB, pq->u.query.vertices)); + GL_EXTCALL(glBeginQuery(GL_PRIMITIVES_SUBMITTED_ARB, pq->u.query.primitives)); + GL_EXTCALL(glBeginQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB, pq->u.query.vertex_shader)); + GL_EXTCALL(glBeginQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB, pq->u.query.tess_control_shader)); + GL_EXTCALL(glBeginQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB, pq->u.query.tess_eval_shader)); + GL_EXTCALL(glBeginQuery(GL_GEOMETRY_SHADER_INVOCATIONS, pq->u.query.geometry_shader)); + GL_EXTCALL(glBeginQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB, pq->u.query.geometry_primitives)); + GL_EXTCALL(glBeginQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB, pq->u.query.fragment_shader)); + GL_EXTCALL(glBeginQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB, pq->u.query.compute_shader)); + GL_EXTCALL(glBeginQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB, pq->u.query.clipping_input)); + GL_EXTCALL(glBeginQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB, pq->u.query.clipping_output)); + checkGLcall("begin query"); + + context_release(context); + pq->started = TRUE; + } + if (flags & WINED3DISSUE_END) + { + if (pq->started) + { + if ((context = context_reacquire(device, pq->context))) + { + GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB)); + GL_EXTCALL(glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS)); + GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB)); + GL_EXTCALL(glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB)); + GL_EXTCALL(glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB)); + GL_EXTCALL(glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB)); + checkGLcall("end query"); + + context_release(context); + poll = TRUE; + } + else + { + FIXME("Wrong thread, can't end query.\n"); + } + } + pq->started = FALSE; + } + + return poll; +} + static const struct wined3d_query_ops event_query_ops = { - wined3d_event_query_ops_get_data, wined3d_event_query_ops_poll, wined3d_event_query_ops_issue, }; +static HRESULT wined3d_event_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_event_query *object; + + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + if (!wined3d_event_query_supported(gl_info)) + { + WARN("Event queries not supported.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(&object->query, device, type, &object->signalled, + sizeof(object->signalled), &event_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = &object->query; + + return WINED3D_OK; +} + static const struct wined3d_query_ops occlusion_query_ops = { - wined3d_occlusion_query_ops_get_data, wined3d_occlusion_query_ops_poll, wined3d_occlusion_query_ops_issue, }; +static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_occlusion_query *object; + + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + if (!gl_info->supported[ARB_OCCLUSION_QUERY]) + { + WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(&object->query, device, type, &object->samples, + sizeof(object->samples), &occlusion_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = &object->query; + + return WINED3D_OK; +} + static const struct wined3d_query_ops timestamp_query_ops = { - wined3d_timestamp_query_ops_get_data, wined3d_timestamp_query_ops_poll, wined3d_timestamp_query_ops_issue, }; -static const struct wined3d_query_ops timestamp_disjoint_query_ops = +static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) { - wined3d_timestamp_disjoint_query_ops_get_data, - wined3d_timestamp_disjoint_query_ops_poll, -#else /* STAGING_CSMT */ -static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) -{ - TRACE("query %p, flags %#x.\n", query, flags); + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_timestamp_query *object; - if (flags & WINED3DISSUE_BEGIN) - query->state = QUERY_BUILDING; - if (flags & WINED3DISSUE_END) - query->state = QUERY_SIGNALLED; + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + if (!gl_info->supported[ARB_TIMER_QUERY]) + { + WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(&object->query, device, type, &object->timestamp, + sizeof(object->timestamp), ×tamp_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = &object->query; return WINED3D_OK; } -static const struct wined3d_query_ops event_query_ops = -{ - wined3d_event_query_ops_get_data, - wined3d_event_query_ops_issue, -}; - -static const struct wined3d_query_ops occlusion_query_ops = -{ - wined3d_occlusion_query_ops_get_data, - wined3d_occlusion_query_ops_issue, -}; - -static const struct wined3d_query_ops timestamp_query_ops = -{ - wined3d_timestamp_query_ops_get_data, - wined3d_timestamp_query_ops_issue, -}; - static const struct wined3d_query_ops timestamp_disjoint_query_ops = { - wined3d_timestamp_disjoint_query_ops_get_data, -#endif /* STAGING_CSMT */ + wined3d_timestamp_disjoint_query_ops_poll, wined3d_timestamp_disjoint_query_ops_issue, }; -static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *device, - enum wined3d_query_type type, void *parent) +static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_query *object; - query->parent = parent; + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); - switch (type) + if (!gl_info->supported[ARB_TIMER_QUERY]) { - case WINED3D_QUERY_TYPE_OCCLUSION: - TRACE("Occlusion query.\n"); - if (!gl_info->supported[ARB_OCCLUSION_QUERY]) - { - WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n"); - return WINED3DERR_NOTAVAILABLE; - } - query->query_ops = &occlusion_query_ops; - query->data_size = sizeof(DWORD); -#if defined(STAGING_CSMT) - query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(struct wined3d_occlusion_query)); - if (!query->extendedData) - { - ERR("Failed to allocate occlusion query extended data.\n"); - return E_OUTOFMEMORY; - } -#else /* STAGING_CSMT */ - query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); - if (!query->extendedData) - { - ERR("Failed to allocate occlusion query extended data.\n"); - return E_OUTOFMEMORY; - } - ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL; -#endif /* STAGING_CSMT */ - break; - - case WINED3D_QUERY_TYPE_EVENT: - TRACE("Event query.\n"); - if (!wined3d_event_query_supported(gl_info)) - { - /* Half-Life 2 needs this query. It does not render the main - * menu correctly otherwise. Pretend to support it, faking - * this query does not do much harm except potentially - * lowering performance. */ - FIXME("Event query: Unimplemented, but pretending to be supported.\n"); - } - query->query_ops = &event_query_ops; - query->data_size = sizeof(BOOL); - query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query)); - if (!query->extendedData) - { - ERR("Failed to allocate event query memory.\n"); - return E_OUTOFMEMORY; - } - break; - - case WINED3D_QUERY_TYPE_TIMESTAMP: - TRACE("Timestamp query.\n"); - if (!gl_info->supported[ARB_TIMER_QUERY]) - { - WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n"); - return WINED3DERR_NOTAVAILABLE; - } - query->query_ops = ×tamp_query_ops; - query->data_size = sizeof(UINT64); - query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_timestamp_query)); - if (!query->extendedData) - { - ERR("Failed to allocate timestamp query extended data.\n"); - return E_OUTOFMEMORY; - } - ((struct wined3d_timestamp_query *)query->extendedData)->context = NULL; - break; - - case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT: - case WINED3D_QUERY_TYPE_TIMESTAMP_FREQ: - TRACE("TIMESTAMP_DISJOINT query.\n"); - if (!gl_info->supported[ARB_TIMER_QUERY]) - { - WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n"); - return WINED3DERR_NOTAVAILABLE; - } - query->query_ops = ×tamp_disjoint_query_ops; - query->data_size = type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT - ? sizeof(struct wined3d_query_data_timestamp_disjoint) : sizeof(UINT64); - query->extendedData = NULL; - break; - - case WINED3D_QUERY_TYPE_VCACHE: - case WINED3D_QUERY_TYPE_RESOURCE_MANAGER: - case WINED3D_QUERY_TYPE_VERTEX_STATS: - case WINED3D_QUERY_TYPE_PIPELINE_TIMINGS: - case WINED3D_QUERY_TYPE_INTERFACE_TIMINGS: - case WINED3D_QUERY_TYPE_VERTEX_TIMINGS: - case WINED3D_QUERY_TYPE_PIXEL_TIMINGS: - case WINED3D_QUERY_TYPE_BANDWIDTH_TIMINGS: - case WINED3D_QUERY_TYPE_CACHE_UTILIZATION: - default: - FIXME("Unhandled query type %#x.\n", type); - return WINED3DERR_NOTAVAILABLE; + WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n"); + return WINED3DERR_NOTAVAILABLE; } - query->type = type; - query->state = QUERY_CREATED; - query->device = device; - query->ref = 1; -#if defined(STAGING_CSMT) - list_init(&query->poll_list_entry); -#endif /* STAGING_CSMT */ - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_query_create(struct wined3d_device *device, - enum wined3d_query_type type, void *parent, struct wined3d_query **query) -{ - struct wined3d_query *object; - HRESULT hr; - - TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query); - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = query_init(object, device, type, parent))) + if (type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) { - WARN("Failed to initialize query, hr %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); - return hr; + static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; + + wined3d_query_init(object, device, type, &disjoint_data, + sizeof(disjoint_data), ×tamp_disjoint_query_ops, parent, parent_ops); + } + else + { + static const UINT64 freq = 1000 * 1000 * 1000; + + wined3d_query_init(object, device, type, &freq, + sizeof(freq), ×tamp_disjoint_query_ops, parent, parent_ops); } TRACE("Created query %p.\n", object); @@ -1192,3 +1143,191 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, return WINED3D_OK; } + +static const struct wined3d_query_ops so_statistics_query_ops = +{ + wined3d_so_statistics_query_ops_poll, + wined3d_so_statistics_query_ops_issue, +}; + +static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_so_statistics_query *object; + + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + if (!gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY]) + { + WARN("OpenGL implementation does not support primitive queries.\n"); + return WINED3DERR_NOTAVAILABLE; + } + if (!gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) + { + WARN("OpenGL implementation does not support indexed queries.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + switch (type) + { + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0: + object->stream_idx = 0; + break; + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1: + object->stream_idx = 1; + break; + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2: + object->stream_idx = 2; + break; + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3: + object->stream_idx = 3; + break; + default: + HeapFree(GetProcessHeap(), 0, object); + return WINED3DERR_NOTAVAILABLE; + } + + wined3d_query_init(&object->query, device, type, &object->statistics, + sizeof(object->statistics), &so_statistics_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = &object->query; + + return WINED3D_OK; +} + +static const struct wined3d_query_ops statistics_query_ops = +{ + wined3d_statistics_query_ops_poll, + wined3d_statistics_query_ops_issue, +}; + +static HRESULT wined3d_statistics_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + static const struct wined3d_query_data_so_statistics statistics = { 1, 1 }; + struct wined3d_query *object; + + FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(object, device, type, &statistics, + sizeof(statistics), &statistics_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = object; + + return WINED3D_OK; +} + +static const struct wined3d_query_ops overflow_query_ops = +{ + wined3d_overflow_query_ops_poll, + wined3d_overflow_query_ops_issue, +}; + +static HRESULT wined3d_overflow_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + static const BOOL overflow = FALSE; + struct wined3d_query *object; + + FIXME("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(object, device, type, &overflow, + sizeof(overflow), &overflow_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = object; + + return WINED3D_OK; +} + +static const struct wined3d_query_ops pipeline_query_ops = +{ + wined3d_pipeline_query_ops_poll, + wined3d_pipeline_query_ops_issue, +}; + +static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device, + enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_query **query) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_pipeline_statistics_query *object; + + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + if (!gl_info->supported[ARB_PIPELINE_STATISTICS_QUERY]) + { + WARN("OpenGL implementation does not support pipeline statistic queries.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_query_init(&object->query, device, type, &object->statistics, + sizeof(object->statistics), &pipeline_query_ops, parent, parent_ops); + + TRACE("Created query %p.\n", object); + *query = &object->query; + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) +{ + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + switch (type) + { + case WINED3D_QUERY_TYPE_EVENT: + return wined3d_event_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_OCCLUSION: + return wined3d_occlusion_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_TIMESTAMP: + return wined3d_timestamp_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT: + case WINED3D_QUERY_TYPE_TIMESTAMP_FREQ: + return wined3d_timestamp_disjoint_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0: + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1: + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2: + case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3: + return wined3d_so_statistics_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_SO_STATISTICS: + return wined3d_statistics_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_SO_OVERFLOW: + return wined3d_overflow_query_create(device, type, parent, parent_ops, query); + + case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS: + return wined3d_pipeline_query_create(device, type, parent, parent_ops, query); + + default: + FIXME("Unhandled query type %#x.\n", type); + return WINED3DERR_NOTAVAILABLE; + } +} diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index c1420413c84..8b310d21854 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -55,6 +55,7 @@ static void resource_check_usage(DWORD usage) | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY + | WINED3DUSAGE_PRIVATE | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; @@ -95,6 +96,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource_types[] = { {WINED3D_RTYPE_BUFFER, 0, WINED3D_GL_RES_TYPE_BUFFER}, + {WINED3D_RTYPE_TEXTURE_1D, 0, WINED3D_GL_RES_TYPE_TEX_1D}, {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_2D}, {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_RECT}, {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_RB}, @@ -211,92 +213,65 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * ERR("Failed to allocate system memory.\n"); return E_OUTOFMEMORY; } -#if defined(STAGING_CSMT) - resource->heap_memory = resource->map_heap_memory; -#endif /* STAGING_CSMT */ } else { resource->heap_memory = NULL; } - /* Check that we have enough video ram left */ - if (pool == WINED3D_POOL_DEFAULT && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING) + if (!(usage & WINED3DUSAGE_PRIVATE)) { - if (size > wined3d_device_get_available_texture_mem(device)) + /* Check that we have enough video ram left */ + if (pool == WINED3D_POOL_DEFAULT && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING) { - ERR("Out of adapter memory\n"); - wined3d_resource_free_sysmem(resource); - return WINED3DERR_OUTOFVIDEOMEMORY; + if (size > wined3d_device_get_available_texture_mem(device)) + { + ERR("Out of adapter memory\n"); + wined3d_resource_free_sysmem(resource); + return WINED3DERR_OUTOFVIDEOMEMORY; + } + adapter_adjust_memory(device->adapter, size); } - adapter_adjust_memory(device->adapter, size); - } - device_resource_add(device, resource); + device_resource_add(device, resource); + } return WINED3D_OK; } -#if defined(STAGING_CSMT) -void wined3d_resource_free_bo(struct wined3d_resource *resource) +static void wined3d_resource_destroy_object(void *object) { - struct wined3d_context *context = context_acquire(resource->device, NULL); - - if (resource->buffer != resource->map_buffer) - ERR("Releasing resource buffer with buffer != map_buffer.\n"); - - wined3d_device_release_bo(resource->device, resource->buffer, context); - resource->buffer = NULL; - resource->map_buffer = NULL; - - context_release(context); -} - -void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) -{ - context_resource_released(resource->device, resource, resource->type); - - if (resource->buffer) - wined3d_resource_free_bo(resource); + struct wined3d_resource *resource = object; wined3d_resource_free_sysmem(resource); - resource->map_heap_memory = NULL; + context_resource_released(resource->device, resource, resource->type); + wined3d_resource_release(resource); } -#endif /* STAGING_CSMT */ void resource_cleanup(struct wined3d_resource *resource) { const struct wined3d *d3d = resource->device->wined3d; TRACE("Cleaning up resource %p.\n", resource); - if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) + if (!(resource->usage & WINED3DUSAGE_PRIVATE)) { - TRACE("Decrementing device memory pool by %u.\n", resource->size); - adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) + { + TRACE("Decrementing device memory pool by %u.\n", resource->size); + adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + } + + device_resource_released(resource->device, resource); } - -#if defined(STAGING_CSMT) - wined3d_cs_emit_resource_cleanup(resource->device->cs, resource); -#else /* STAGING_CSMT */ - wined3d_resource_free_sysmem(resource); -#endif /* STAGING_CSMT */ - - device_resource_released(resource->device, resource); + wined3d_resource_acquire(resource); + wined3d_cs_destroy_object(resource->device->cs, wined3d_resource_destroy_object, resource); } void resource_unload(struct wined3d_resource *resource) { if (resource->map_count) ERR("Resource %p is being unloaded while mapped.\n", resource); - -#if defined(STAGING_CSMT) - if (resource->buffer) - wined3d_resource_free_bo(resource); - -#endif /* STAGING_CSMT */ - context_resource_unloaded(resource->device, - resource, resource->type); } DWORD CDECL wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority) @@ -345,55 +320,7 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st desc->size = resource->size; } -HRESULT CDECL wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", - resource, sub_resource_idx, map_desc, debug_box(box), flags); - - return resource->resource_ops->resource_sub_resource_map(resource, sub_resource_idx, map_desc, box, flags); -} - -HRESULT CDECL wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -{ - TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); - - return resource->resource_ops->resource_sub_resource_unmap(resource, sub_resource_idx); -} - -BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) -{ - void **p; - SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); - void *mem; - - if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, resource->size + align))) - return FALSE; - - p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; - *p = mem; - -#if defined(STAGING_CSMT) - resource->map_heap_memory = ++p; -#else /* STAGING_CSMT */ - resource->heap_memory = ++p; -#endif /* STAGING_CSMT */ - - return TRUE; -} - -void wined3d_resource_free_sysmem(struct wined3d_resource *resource) -{ - void **p = resource->heap_memory; - - if (!p) - return; - - HeapFree(GetProcessHeap(), 0, *(--p)); - resource->heap_memory = NULL; -} - -DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) +static DWORD wined3d_resource_sanitise_map_flags(const struct wined3d_resource *resource, DWORD flags) { /* Not all flags make sense together, but Windows never returns an error. * Catch the cases that could cause issues. */ @@ -426,6 +353,66 @@ DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resourc return flags; } +HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) +{ + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", + resource, sub_resource_idx, map_desc, debug_box(box), flags); + + flags = wined3d_resource_sanitise_map_flags(resource, flags); + wined3d_resource_wait_idle(resource); + + return wined3d_cs_map(resource->device->cs, resource, sub_resource_idx, map_desc, box, flags); +} + +HRESULT CDECL wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags) +{ + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); + + return resource->resource_ops->resource_map_info(resource, sub_resource_idx, info, flags); +} + +HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) +{ + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); + + return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx); +} + +void CDECL wined3d_resource_preload(struct wined3d_resource *resource) +{ + wined3d_cs_emit_preload_resource(resource->device->cs, resource); +} + +BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) +{ + void **p; + SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); + void *mem; + + if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, resource->size + align))) + return FALSE; + + p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; + *p = mem; + + resource->heap_memory = ++p; + + return TRUE; +} + +void wined3d_resource_free_sysmem(struct wined3d_resource *resource) +{ + void **p = resource->heap_memory; + + if (!p) + return; + + HeapFree(GetProcessHeap(), 0, *(--p)); + resource->heap_memory = NULL; +} + GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) { GLbitfield ret = 0; @@ -443,11 +430,7 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) return ret; } -#if defined(STAGING_CSMT) -static GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) -#else /* STAGING_CSMT */ GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) -#endif /* STAGING_CSMT */ { if (d3d_flags & WINED3D_MAP_READONLY) return GL_READ_ONLY_ARB; @@ -465,7 +448,7 @@ BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) return TRUE; /* Not on a swapchain - must be offscreen */ - if (!(swapchain = wined3d_texture_from_resource(resource)->swapchain)) + if (!(swapchain = texture_from_resource(resource)->swapchain)) return TRUE; /* The front buffer is always onscreen */ @@ -488,579 +471,3 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) else resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; } -#if defined(STAGING_CSMT) - -void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, - UINT *slice_pitch) -{ - unsigned int alignment; - const struct wined3d_format *format = resource->format; - - if (resource->custom_row_pitch) - { - *row_pitch = resource->custom_row_pitch; - *slice_pitch = resource->custom_slice_pitch; - return; - } - - alignment = resource->device->surface_alignment; - *row_pitch = wined3d_format_calculate_pitch(resource->format, resource->width); - *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) - { - /* Since compressed formats are block based, pitch means the amount of - * bytes to the next row of block rather than the next row of pixels. */ - UINT slice_block_count = (resource->height + format->block_height - 1) / format->block_height; - *slice_pitch = *row_pitch * slice_block_count; - } - else - { - *slice_pitch = *row_pitch * resource->height; - } - - TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch); -} - -void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) -{ - TRACE("Resource %p, setting %s.\n", resource, wined3d_debug_location(location)); - resource->locations |= location; - TRACE("new location flags are %s.\n", wined3d_debug_location(resource->locations)); -} - -void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWORD location) -{ - TRACE("Resource %p, setting %s.\n", resource, wined3d_debug_location(location)); - resource->locations &= ~location; - TRACE("new location flags are %s.\n", wined3d_debug_location(resource->locations)); - - resource->resource_ops->resource_location_invalidated(resource, location); -} - -DWORD wined3d_resource_access_from_location(DWORD location) -{ - switch (location) - { - case WINED3D_LOCATION_DISCARDED: - return 0; - - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_USER_MEMORY: - case WINED3D_LOCATION_DIB: - return WINED3D_RESOURCE_ACCESS_CPU; - - case WINED3D_LOCATION_BUFFER: - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - case WINED3D_LOCATION_DRAWABLE: - case WINED3D_LOCATION_RB_MULTISAMPLE: - case WINED3D_LOCATION_RB_RESOLVED: - return WINED3D_RESOURCE_ACCESS_GPU; - - default: - FIXME("Unhandled location %#x.\n", location); - return 0; - } -} - -void wined3d_resource_get_memory(const struct wined3d_resource *resource, - DWORD location, struct wined3d_bo_address *data) -{ - if (location & WINED3D_LOCATION_BUFFER) - { - data->buffer_object = resource->buffer->name; - data->addr = NULL; - return; - } - if (location & WINED3D_LOCATION_USER_MEMORY) - { - data->buffer_object = 0; - data->addr = resource->user_memory; - return; - } - if (location & WINED3D_LOCATION_DIB) - { - data->buffer_object = 0; - data->addr = resource->bitmap_data; - return; - } - if (location & WINED3D_LOCATION_SYSMEM) - { - data->buffer_object = 0; - data->addr = resource->heap_memory; - return; - } - ERR("Unexpected location %s.\n", wined3d_debug_location(location)); -} - -/* Context activation is optionally by the caller. Context may be NULL. */ -static void wined3d_resource_copy_simple_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - const struct wined3d_gl_info *gl_info; - struct wined3d_bo_address dst, src; - UINT size = resource->size; - - wined3d_resource_get_memory(resource, location, &dst); - wined3d_resource_get_memory(resource, resource->locations, &src); - - if (dst.buffer_object) - { - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); - GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Upload PBO"); - return; - } - if (src.buffer_object) - { - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); - GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("Download PBO"); - return; - } - memcpy(dst.addr, src.addr, size); -} - -/* Context activation is optionally by the caller. Context may be NULL. */ -void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - DWORD required_access = wined3d_resource_access_from_location(location); - DWORD simple_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY - | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; - - if ((resource->locations & location) == location) - { - TRACE("Location(s) already up to date.\n"); - return; - } - - /* Keep this a WARN for now until surfaces are cleaned up. */ - if ((resource->access_flags & required_access) != required_access) - WARN("Operation requires %#x access, but resource only has %#x.\n", - required_access, resource->access_flags); - - if (location & simple_locations) - { - if (resource->locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Resource was discarded, nothing to do.\n"); - resource->locations |= location; - return; - } - if (resource->locations & simple_locations) - { - wined3d_resource_copy_simple_location(resource, context, location); - resource->locations |= location; - return; - } - } - - /* Context is NULL in ddraw-only operation without OpenGL. */ - if (!context) - ERR("A context is required for non-sysmem operation.\n"); - - resource->resource_ops->resource_load_location(resource, context, location); -} - -BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context, DWORD flags) -{ - const struct wined3d_gl_info *gl_info; - BYTE *ptr; - - switch (resource->map_binding) - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); - mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; - ptr = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, - 0, resource->size, mapflags)); - } - else - { - GLenum access = wined3d_resource_gl_legacy_map_flags(flags); - ptr = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); - } - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Map GL buffer"); - return ptr; - - case WINED3D_LOCATION_SYSMEM: - return resource->map_heap_memory; - - case WINED3D_LOCATION_DIB: - return resource->bitmap_data; - - case WINED3D_LOCATION_USER_MEMORY: - return resource->user_memory; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); - return NULL; - } -} - -void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context) -{ - const struct wined3d_gl_info *gl_info; - - switch (resource->map_binding) - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Unmap GL buffer"); - return; - - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_DIB: - case WINED3D_LOCATION_USER_MEMORY: - return; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); - return; - } -} - -/* Context activation is done by the caller. */ -static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struct wined3d_context *context) -{ - if (resource->buffer) - return; - - resource->buffer = wined3d_device_get_bo(resource->device, resource->size, - GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); - resource->map_buffer = resource->buffer; - TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); - resource->map_heap_memory = NULL; -} - -BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) -{ - if (resource->heap_memory) - return TRUE; - - if (!wined3d_resource_allocate_sysmem(resource)) - { - ERR("Failed to allocate system memory.\n"); - return FALSE; - } - resource->heap_memory = resource->map_heap_memory; - return TRUE; -} - -/* Context activation is done by the caller. */ -BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, struct wined3d_context *context) -{ - switch (resource->map_binding) - { - case WINED3D_LOCATION_BUFFER: - wined3d_resource_prepare_bo(resource, context); - return TRUE; - - case WINED3D_LOCATION_SYSMEM: - return wined3d_resource_prepare_system_memory(resource); - - case WINED3D_LOCATION_USER_MEMORY: - if (!resource->user_memory) - ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but resource->user_memory is NULL.\n"); - return TRUE; - - case WINED3D_LOCATION_DIB: - if (!resource->bitmap_data) - ERR("Map binding is set to WINED3D_LOCATION_DIB but resource->bitmap_data is NULL.\n"); - return TRUE; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); - return FALSE; - } -} - -BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) -{ - UINT width_mask, height_mask; - const struct wined3d_format *format = resource->format; - - if (!box) - return TRUE; - - /* This assumes power of two block sizes, but NPOT block sizes would be - * silly anyway. - * - * This also assumes that the format's block depth is 1. */ - width_mask = format->block_width - 1; - height_mask = format->block_height - 1; - - if (box->left & width_mask) - return FALSE; - if (box->top & height_mask) - return FALSE; - if (box->right & width_mask && box->right != resource->width) - return FALSE; - if (box->bottom & height_mask && box->bottom != resource->height) - return FALSE; - - return TRUE; -} - -void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) -{ - struct wined3d_device *device = resource->device; - struct wined3d_context *context = NULL; - void *mem; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - if (!wined3d_resource_prepare_map_memory(resource, context)) - { - WARN("Out of memory.\n"); - context_release(context); - return NULL; - } - - if (flags & WINED3D_MAP_DISCARD) - { - switch (resource->map_binding) - { - case WINED3D_LOCATION_BUFFER: - resource->map_buffer = wined3d_device_get_bo(device, resource->size, - GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); - break; - - case WINED3D_LOCATION_SYSMEM: - wined3d_resource_allocate_sysmem(resource); - break; - - default: - if (resource->access_fence) - ERR("Location %s does not support DISCARD maps.\n", - wined3d_debug_location(resource->map_binding)); - if (resource->pool != WINED3D_POOL_DEFAULT) - FIXME("Discard used on %s pool resource.\n", debug_d3dpool(resource->pool)); - } - wined3d_resource_validate_location(resource, resource->map_binding); - } - else - { - wined3d_resource_load_location(resource, context, resource->map_binding); - } - - mem = wined3d_resource_get_map_ptr(resource, context, flags); - - if (context) - context_release(context); - - return mem; -} - -static void wined3d_resource_sync(struct wined3d_resource *resource) -{ - struct wined3d_resource *real_res = resource; - struct wined3d_surface *surface; - struct wined3d_volume *volume; - - switch (resource->type) - { - case WINED3D_RTYPE_SURFACE: - surface = surface_from_resource(resource); - if (surface->container) - real_res = &surface->container->resource; - break; - - case WINED3D_RTYPE_VOLUME: - volume = volume_from_resource(resource); - real_res = &volume->container->resource; - break; - - default: - break; - } - wined3d_resource_wait_fence(real_res); -} - -HRESULT wined3d_resource_map(struct wined3d_resource *resource, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_device *device = resource->device; - BYTE *base_memory; - const struct wined3d_format *format = resource->format; - const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; - - TRACE("resource %p, map_desc %p, box %s, flags %#x.\n", - resource, map_desc, debug_box(box), flags); - - if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) - { - WARN("Ignoring render target map, only finishing CS.\n"); - wined3d_cs_emit_glfinish(device->cs); - map_desc->row_pitch = 0; - map_desc->slice_pitch = 0; - map_desc->data = NULL; - device->cs->ops->finish(device->cs); - return WINED3D_OK; - } - - if (resource->map_count) - { - WARN("Volume is already mapped.\n"); - return WINED3DERR_INVALIDCALL; - } - - flags = wined3d_resource_sanitize_map_flags(resource, flags); - - if (flags & WINED3D_MAP_NOOVERWRITE) - FIXME("WINED3D_MAP_NOOVERWRITE are not implemented yet.\n"); - - if (flags & WINED3D_MAP_DISCARD) - { - switch (resource->map_binding) - { - case WINED3D_LOCATION_BUFFER: - case WINED3D_LOCATION_SYSMEM: - break; - - default: - FIXME("Implement discard maps with %s map binding.\n", - wined3d_debug_location(resource->map_binding)); - wined3d_resource_sync(resource); - } - } - else - wined3d_resource_sync(resource); - - base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); - if (!base_memory) - { - WARN("Map failed.\n"); - return WINED3DERR_INVALIDCALL; - } - - TRACE("Base memory pointer %p.\n", base_memory); - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) - { - map_desc->row_pitch = resource->width * format->byte_count; - map_desc->slice_pitch = map_desc->row_pitch * resource->height; - } - else - { - wined3d_resource_get_pitch(resource, &map_desc->row_pitch, &map_desc->slice_pitch); - } - - if (!box) - { - map_desc->data = base_memory; - } - else - { - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) - { - /* Compressed textures are block based, so calculate the offset of - * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = base_memory - + (box->front * map_desc->slice_pitch) - + ((box->top / format->block_height) * map_desc->row_pitch) - + ((box->left / format->block_width) * format->block_byte_count); - } - else - { - map_desc->data = base_memory - + (map_desc->slice_pitch * box->front) - + (map_desc->row_pitch * box->top) - + (box->left * format->byte_count); - } - } - - if (!(flags & WINED3D_MAP_READONLY)) - resource->unmap_dirtify = TRUE; - - resource->map_count++; - - TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", - map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); - - return WINED3D_OK; -} - -void wined3d_resource_unmap_internal(struct wined3d_resource *resource) -{ - struct wined3d_device *device = resource->device; - struct wined3d_context *context = NULL; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - wined3d_resource_release_map_ptr(resource, context); - if (context) - context_release(context); -} - -HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -{ - struct wined3d_device *device = resource->device; - TRACE("resource %p.\n", resource); - - if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) - { - WARN("Ignoring render target unmap.\n"); - return WINED3D_OK; - } - - if (!resource->map_count) - { - WARN("Trying to unlock an unlocked resource %p.\n", resource); - return WINEDDERR_NOTLOCKED; - } - - wined3d_cs_emit_resource_unmap(device->cs, resource); - - if (resource->unmap_dirtify) - { - wined3d_cs_emit_resource_changed(device->cs, resource, - resource->map_buffer, resource->map_heap_memory); - } - resource->unmap_dirtify = FALSE; - - resource->map_count--; - - return WINED3D_OK; -} - -void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer, - void *swap_heap_memory) -{ - struct wined3d_device *device = resource->device; - - if (swap_buffer && swap_buffer != resource->buffer) - { - struct wined3d_context *context = context_acquire(device, NULL); - wined3d_device_release_bo(device, resource->buffer, context); - context_release(context); - resource->buffer = swap_buffer; - } - if (swap_heap_memory && swap_heap_memory != resource->heap_memory) - { - wined3d_resource_free_sysmem(resource); - resource->heap_memory = swap_heap_memory; - } - - wined3d_resource_invalidate_location(resource, ~resource->map_binding); -} -#endif /* STAGING_CSMT */ diff --git a/reactos/dll/directx/wine/wined3d/sampler.c b/reactos/dll/directx/wine/wined3d/sampler.c index 9a68ec8a1ae..0ddeed5e914 100644 --- a/reactos/dll/directx/wine/wined3d/sampler.c +++ b/reactos/dll/directx/wine/wined3d/sampler.c @@ -30,14 +30,19 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler) return refcount; } -#if defined(STAGING_CSMT) -void wined3d_sampler_destroy(struct wined3d_sampler *sampler) +static void wined3d_sampler_destroy_object(void *object) { - struct wined3d_context *context = context_acquire(sampler->device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_sampler *sampler = object; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; - GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); - context_release(context); + if (sampler->name) + { + context = context_acquire(sampler->device, NULL, 0); + gl_info = context->gl_info; + GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); + context_release(context); + } HeapFree(GetProcessHeap(), 0, sampler); } @@ -50,26 +55,8 @@ ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) if (!refcount) { - struct wined3d_device *device = sampler->device; - wined3d_cs_emit_sampler_destroy(device->cs, sampler); -#else /* STAGING_CSMT */ -ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) -{ - ULONG refcount = InterlockedDecrement(&sampler->refcount); - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - TRACE("%p decreasing refcount to %u.\n", sampler, refcount); - - if (!refcount) - { - context = context_acquire(sampler->device, NULL); - gl_info = context->gl_info; - GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); - context_release(context); - - HeapFree(GetProcessHeap(), 0, sampler); -#endif /* STAGING_CSMT */ + sampler->parent_ops->wined3d_object_destroyed(sampler->parent); + wined3d_cs_destroy_object(sampler->device->cs, wined3d_sampler_destroy_object, sampler); } return refcount; @@ -82,20 +69,17 @@ void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler) return sampler->parent; } -static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device, - const struct wined3d_sampler_desc *desc, void *parent) +static void wined3d_sampler_cs_init(void *object) { + struct wined3d_sampler *sampler = object; + const struct wined3d_sampler_desc *desc; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - sampler->refcount = 1; - sampler->device = device; - sampler->parent = parent; - sampler->desc = *desc; - - context = context_acquire(device, NULL); + context = context_acquire(sampler->device, NULL, 0); gl_info = context->gl_info; + desc = &sampler->desc; GL_EXTCALL(glGenSamplers(1, &sampler->name)); GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S, gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP])); @@ -127,16 +111,26 @@ static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d context_release(context); } +static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device, + const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + sampler->refcount = 1; + sampler->device = device; + sampler->parent = parent; + sampler->parent_ops = parent_ops; + sampler->desc = *desc; + + if (device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS]) + wined3d_cs_init_object(device->cs, wined3d_sampler_cs_init, sampler); +} + HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, - void *parent, struct wined3d_sampler **sampler) + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler) { struct wined3d_sampler *object; TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler); - if (!device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS]) - return WINED3DERR_INVALIDCALL; - if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE || desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE || desc->address_w < WINED3D_TADDRESS_WRAP || desc->address_w > WINED3D_TADDRESS_MIRROR_ONCE) @@ -150,10 +144,59 @@ HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - wined3d_sampler_init(object, device, desc, parent); + wined3d_sampler_init(object, device, desc, parent, parent_ops); TRACE("Created sampler %p.\n", object); *sampler = object; return WINED3D_OK; } + +static void texture_apply_base_level(struct wined3d_texture *texture, + const struct wined3d_sampler_desc *desc, const struct wined3d_gl_info *gl_info) +{ + struct gl_texture *gl_tex; + unsigned int base_level; + + if (texture->flags & WINED3D_TEXTURE_COND_NP2) + base_level = 0; + else if (desc->mip_filter == WINED3D_TEXF_NONE) + base_level = texture->lod; + else + base_level = min(max(desc->mip_base_level, texture->lod), texture->level_count - 1); + + gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB); + if (base_level != gl_tex->base_level) + { + /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap + * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest + * mipmap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL + * corresponds to GL_TEXTURE_BASE_LEVEL. */ + gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level); + gl_tex->base_level = base_level; + } +} + +/* This function relies on the correct texture being bound and loaded. */ +void wined3d_sampler_bind(struct wined3d_sampler *sampler, unsigned int unit, + struct wined3d_texture *texture, const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + { + GL_EXTCALL(glBindSampler(unit, sampler->name)); + checkGLcall("bind sampler"); + } + else if (texture) + { + wined3d_texture_apply_sampler_desc(texture, &sampler->desc, context); + } + else + { + ERR("Could not apply sampler state.\n"); + } + + if (texture) + texture_apply_base_level(texture, &sampler->desc, gl_info); +} diff --git a/reactos/dll/directx/wine/wined3d/shader.c b/reactos/dll/directx/wine/wined3d/shader.c index efbfda67a23..1545d28882a 100644 --- a/reactos/dll/directx/wine/wined3d/shader.c +++ b/reactos/dll/directx/wine/wined3d/shader.c @@ -33,148 +33,243 @@ const float wined3d_srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; static const char * const shader_opcode_names[] = { - /* WINED3DSIH_ABS */ "abs", - /* WINED3DSIH_ADD */ "add", - /* WINED3DSIH_AND */ "and", - /* WINED3DSIH_BEM */ "bem", - /* WINED3DSIH_BREAK */ "break", - /* WINED3DSIH_BREAKC */ "breakc", - /* WINED3DSIH_BREAKP */ "breakp", - /* WINED3DSIH_CALL */ "call", - /* WINED3DSIH_CALLNZ */ "callnz", - /* WINED3DSIH_CMP */ "cmp", - /* WINED3DSIH_CND */ "cnd", - /* WINED3DSIH_CRS */ "crs", - /* WINED3DSIH_CUT */ "cut", - /* WINED3DSIH_DCL */ "dcl", - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ "dcl_constantBuffer", - /* WINED3DSIH_DCL_GLOBAL_FLAGS */ "dcl_globalFlags", - /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ "dcl_immediateConstantBuffer", - /* WINED3DSIH_DCL_INPUT */ "dcl_input", - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ "dcl_inputPrimitive", - /* WINED3DSIH_DCL_INPUT_PS */ "dcl_input_ps", - /* WINED3DSIH_DCL_INPUT_PS_SGV */ "dcl_input_ps_sgv", - /* WINED3DSIH_DCL_INPUT_PS_SIV */ "dcl_input_ps_siv", - /* WINED3DSIH_DCL_INPUT_SGV */ "dcl_input_sgv", - /* WINED3DSIH_DCL_INPUT_SIV */ "dcl_input_siv", - /* WINED3DSIH_DCL_OUTPUT */ "dcl_output", - /* WINED3DSIH_DCL_OUTPUT_SIV */ "dcl_output_siv", - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ "dcl_outputTopology", - /* WINED3DSIH_DCL_SAMPLER */ "dcl_sampler", - /* WINED3DSIH_DCL_TEMPS */ "dcl_temps", - /* WINED3DSIH_DCL_VERTICES_OUT */ "dcl_maxOutputVertexCount", - /* WINED3DSIH_DEF */ "def", - /* WINED3DSIH_DEFB */ "defb", - /* WINED3DSIH_DEFI */ "defi", - /* WINED3DSIH_DIV */ "div", - /* WINED3DSIH_DP2 */ "dp2", - /* WINED3DSIH_DP2ADD */ "dp2add", - /* WINED3DSIH_DP3 */ "dp3", - /* WINED3DSIH_DP4 */ "dp4", - /* WINED3DSIH_DST */ "dst", - /* WINED3DSIH_DSX */ "dsx", - /* WINED3DSIH_DSY */ "dsy", - /* WINED3DSIH_ELSE */ "else", - /* WINED3DSIH_EMIT */ "emit", - /* WINED3DSIH_ENDIF */ "endif", - /* WINED3DSIH_ENDLOOP */ "endloop", - /* WINED3DSIH_ENDREP */ "endrep", - /* WINED3DSIH_EQ */ "eq", - /* WINED3DSIH_EXP */ "exp", - /* WINED3DSIH_EXPP */ "expp", - /* WINED3DSIH_FRC */ "frc", - /* WINED3DSIH_FTOI */ "ftoi", - /* WINED3DSIH_FTOU */ "ftou", - /* WINED3DSIH_GE */ "ge", - /* WINED3DSIH_IADD */ "iadd", - /* WINED3DSIH_IEQ */ "ieq", - /* WINED3DSIH_IF */ "if", - /* WINED3DSIH_IFC */ "ifc", - /* WINED3DSIH_IGE */ "ige", - /* WINED3DSIH_ILT */ "ilt", - /* WINED3DSIH_IMAD */ "imad", - /* WINED3DSIH_IMAX */ "imax", - /* WINED3DSIH_IMIN */ "imin", - /* WINED3DSIH_IMUL */ "imul", - /* WINED3DSIH_INE */ "ine", - /* WINED3DSIH_INEG */ "ineg", - /* WINED3DSIH_ISHL */ "ishl", - /* WINED3DSIH_ITOF */ "itof", - /* WINED3DSIH_LABEL */ "label", - /* WINED3DSIH_LD */ "ld", - /* WINED3DSIH_LIT */ "lit", - /* WINED3DSIH_LOG */ "log", - /* WINED3DSIH_LOGP */ "logp", - /* WINED3DSIH_LOOP */ "loop", - /* WINED3DSIH_LRP */ "lrp", - /* WINED3DSIH_LT */ "lt", - /* WINED3DSIH_M3x2 */ "m3x2", - /* WINED3DSIH_M3x3 */ "m3x3", - /* WINED3DSIH_M3x4 */ "m3x4", - /* WINED3DSIH_M4x3 */ "m4x3", - /* WINED3DSIH_M4x4 */ "m4x4", - /* WINED3DSIH_MAD */ "mad", - /* WINED3DSIH_MAX */ "max", - /* WINED3DSIH_MIN */ "min", - /* WINED3DSIH_MOV */ "mov", - /* WINED3DSIH_MOVA */ "mova", - /* WINED3DSIH_MOVC */ "movc", - /* WINED3DSIH_MUL */ "mul", - /* WINED3DSIH_NE */ "ne", - /* WINED3DSIH_NOP */ "nop", - /* WINED3DSIH_NOT */ "not", - /* WINED3DSIH_NRM */ "nrm", - /* WINED3DSIH_OR */ "or", - /* WINED3DSIH_PHASE */ "phase", - /* WINED3DSIH_POW */ "pow", - /* WINED3DSIH_RCP */ "rcp", - /* WINED3DSIH_REP */ "rep", - /* WINED3DSIH_RESINFO */ "resinfo", - /* WINED3DSIH_RET */ "ret", - /* WINED3DSIH_ROUND_NI */ "round_ni", - /* WINED3DSIH_ROUND_PI */ "round_pi", - /* WINED3DSIH_ROUND_Z */ "round_z", - /* WINED3DSIH_RSQ */ "rsq", - /* WINED3DSIH_SAMPLE */ "sample", - /* WINED3DSIH_SAMPLE_B */ "sample_b", - /* WINED3DSIH_SAMPLE_C */ "sample_c", - /* WINED3DSIH_SAMPLE_C_LZ */ "sample_c_lz", - /* WINED3DSIH_SAMPLE_GRAD */ "sample_d", - /* WINED3DSIH_SAMPLE_LOD */ "sample_l", - /* WINED3DSIH_SETP */ "setp", - /* WINED3DSIH_SGE */ "sge", - /* WINED3DSIH_SGN */ "sgn", - /* WINED3DSIH_SINCOS */ "sincos", - /* WINED3DSIH_SLT */ "slt", - /* WINED3DSIH_SQRT */ "sqrt", - /* WINED3DSIH_SUB */ "sub", - /* WINED3DSIH_TEX */ "texld", - /* WINED3DSIH_TEXBEM */ "texbem", - /* WINED3DSIH_TEXBEML */ "texbeml", - /* WINED3DSIH_TEXCOORD */ "texcrd", - /* WINED3DSIH_TEXDEPTH */ "texdepth", - /* WINED3DSIH_TEXDP3 */ "texdp3", - /* WINED3DSIH_TEXDP3TEX */ "texdp3tex", - /* WINED3DSIH_TEXKILL */ "texkill", - /* WINED3DSIH_TEXLDD */ "texldd", - /* WINED3DSIH_TEXLDL */ "texldl", - /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth", - /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad", - /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex", - /* WINED3DSIH_TEXM3x3 */ "texm3x3", - /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff", - /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad", - /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec", - /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex", - /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec", - /* WINED3DSIH_TEXREG2AR */ "texreg2ar", - /* WINED3DSIH_TEXREG2GB */ "texreg2gb", - /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb", - /* WINED3DSIH_UDIV */ "udiv", - /* WINED3DSIH_UGE */ "uge", - /* WINED3DSIH_USHR */ "ushr", - /* WINED3DSIH_UTOF */ "utof", - /* WINED3DSIH_XOR */ "xor", + /* WINED3DSIH_ABS */ "abs", + /* WINED3DSIH_ADD */ "add", + /* WINED3DSIH_AND */ "and", + /* WINED3DSIH_ATOMIC_AND */ "atomic_and", + /* WINED3DSIH_ATOMIC_CMP_STORE */ "atomic_cmp_store", + /* WINED3DSIH_ATOMIC_IADD */ "atomic_iadd", + /* WINED3DSIH_ATOMIC_IMAX */ "atomic_imax", + /* WINED3DSIH_ATOMIC_IMIN */ "atomic_imin", + /* WINED3DSIH_ATOMIC_OR */ "atomic_or", + /* WINED3DSIH_ATOMIC_UMAX */ "atomic_umax", + /* WINED3DSIH_ATOMIC_UMIN */ "atomic_umin", + /* WINED3DSIH_ATOMIC_XOR */ "atomic_xor", + /* WINED3DSIH_BEM */ "bem", + /* WINED3DSIH_BFI */ "bfi", + /* WINED3DSIH_BFREV */ "bfrev", + /* WINED3DSIH_BREAK */ "break", + /* WINED3DSIH_BREAKC */ "breakc", + /* WINED3DSIH_BREAKP */ "breakp", + /* WINED3DSIH_BUFINFO */ "bufinfo", + /* WINED3DSIH_CALL */ "call", + /* WINED3DSIH_CALLNZ */ "callnz", + /* WINED3DSIH_CASE */ "case", + /* WINED3DSIH_CMP */ "cmp", + /* WINED3DSIH_CND */ "cnd", + /* WINED3DSIH_CONTINUE */ "continue", + /* WINED3DSIH_CONTINUEP */ "continuec", + /* WINED3DSIH_COUNTBITS */ "countbits", + /* WINED3DSIH_CRS */ "crs", + /* WINED3DSIH_CUT */ "cut", + /* WINED3DSIH_CUT_STREAM */ "cut_stream", + /* WINED3DSIH_DCL */ "dcl", + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ "dcl_constantBuffer", + /* WINED3DSIH_DCL_FUNCTION_BODY */ "dcl_function_body", + /* WINED3DSIH_DCL_FUNCTION_TABLE */ "dcl_function_table", + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ "dcl_globalFlags", + /* WINED3DSIH_DCL_GS_INSTANCES */ "dcl_gs_instances", + /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ "dcl_hs_fork_phase_instance_count", + /* WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT */ "dcl_hs_join_phase_instance_count", + /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR */ "dcl_hs_max_tessfactor", + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ "dcl_immediateConstantBuffer", + /* WINED3DSIH_DCL_INDEX_RANGE */ "dcl_index_range", + /* WINED3DSIH_DCL_INDEXABLE_TEMP */ "dcl_indexableTemp", + /* WINED3DSIH_DCL_INPUT */ "dcl_input", + /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ "dcl_input_control_point_count", + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ "dcl_inputPrimitive", + /* WINED3DSIH_DCL_INPUT_PS */ "dcl_input_ps", + /* WINED3DSIH_DCL_INPUT_PS_SGV */ "dcl_input_ps_sgv", + /* WINED3DSIH_DCL_INPUT_PS_SIV */ "dcl_input_ps_siv", + /* WINED3DSIH_DCL_INPUT_SGV */ "dcl_input_sgv", + /* WINED3DSIH_DCL_INPUT_SIV */ "dcl_input_siv", + /* WINED3DSIH_DCL_INTERFACE */ "dcl_interface", + /* WINED3DSIH_DCL_OUTPUT */ "dcl_output", + /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT */ "dcl_output_control_point_count", + /* WINED3DSIH_DCL_OUTPUT_SIV */ "dcl_output_siv", + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ "dcl_outputTopology", + /* WINED3DSIH_DCL_RESOURCE_RAW */ "dcl_resource_raw", + /* WINED3DSIH_DCL_RESOURCE_STRUCTURED */ "dcl_resource_structured", + /* WINED3DSIH_DCL_SAMPLER */ "dcl_sampler", + /* WINED3DSIH_DCL_STREAM */ "dcl_stream", + /* WINED3DSIH_DCL_TEMPS */ "dcl_temps", + /* WINED3DSIH_DCL_TESSELLATOR_DOMAIN */ "dcl_tessellator_domain", + /* WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE */ "dcl_tessellator_output_primitive", + /* WINED3DSIH_DCL_TESSELLATOR_PARTITIONING */ "dcl_tessellator_partitioning", + /* WINED3DSIH_DCL_TGSM_RAW */ "dcl_tgsm_raw", + /* WINED3DSIH_DCL_TGSM_STRUCTURED */ "dcl_tgsm_structured", + /* WINED3DSIH_DCL_THREAD_GROUP */ "dcl_thread_group", + /* WINED3DSIH_DCL_UAV_RAW */ "dcl_uav_raw", + /* WINED3DSIH_DCL_UAV_STRUCTURED */ "dcl_uav_structured", + /* WINED3DSIH_DCL_UAV_TYPED */ "dcl_uav_typed", + /* WINED3DSIH_DCL_VERTICES_OUT */ "dcl_maxOutputVertexCount", + /* WINED3DSIH_DEF */ "def", + /* WINED3DSIH_DEFAULT */ "default", + /* WINED3DSIH_DEFB */ "defb", + /* WINED3DSIH_DEFI */ "defi", + /* WINED3DSIH_DIV */ "div", + /* WINED3DSIH_DP2 */ "dp2", + /* WINED3DSIH_DP2ADD */ "dp2add", + /* WINED3DSIH_DP3 */ "dp3", + /* WINED3DSIH_DP4 */ "dp4", + /* WINED3DSIH_DST */ "dst", + /* WINED3DSIH_DSX */ "dsx", + /* WINED3DSIH_DSX_COARSE */ "deriv_rtx_coarse", + /* WINED3DSIH_DSX_FINE */ "deriv_rtx_fine", + /* WINED3DSIH_DSY */ "dsy", + /* WINED3DSIH_DSY_COARSE */ "deriv_rty_coarse", + /* WINED3DSIH_DSY_FINE */ "deriv_rty_fine", + /* WINED3DSIH_ELSE */ "else", + /* WINED3DSIH_EMIT */ "emit", + /* WINED3DSIH_EMIT_STREAM */ "emit_stream", + /* WINED3DSIH_ENDIF */ "endif", + /* WINED3DSIH_ENDLOOP */ "endloop", + /* WINED3DSIH_ENDREP */ "endrep", + /* WINED3DSIH_ENDSWITCH */ "endswitch", + /* WINED3DSIH_EQ */ "eq", + /* WINED3DSIH_EXP */ "exp", + /* WINED3DSIH_EXPP */ "expp", + /* WINED3DSIH_F16TOF32 */ "f16tof32", + /* WINED3DSIH_F32TOF16 */ "f32tof16", + /* WINED3DSIH_FCALL */ "fcall", + /* WINED3DSIH_FIRSTBIT_HI */ "firstbit_hi", + /* WINED3DSIH_FIRSTBIT_LO */ "firstbit_lo", + /* WINED3DSIH_FIRSTBIT_SHI */ "firstbit_shi", + /* WINED3DSIH_FRC */ "frc", + /* WINED3DSIH_FTOI */ "ftoi", + /* WINED3DSIH_FTOU */ "ftou", + /* WINED3DSIH_GATHER4 */ "gather4", + /* WINED3DSIH_GATHER4_C */ "gather4_c", + /* WINED3DSIH_GATHER4_PO */ "gather4_po", + /* WINED3DSIH_GATHER4_PO_C */ "gather4_po_c", + /* WINED3DSIH_GE */ "ge", + /* WINED3DSIH_HS_CONTROL_POINT_PHASE */ "hs_control_point_phase", + /* WINED3DSIH_HS_DECLS */ "hs_decls", + /* WINED3DSIH_HS_FORK_PHASE */ "hs_fork_phase", + /* WINED3DSIH_HS_JOIN_PHASE */ "hs_join_phase", + /* WINED3DSIH_IADD */ "iadd", + /* WINED3DSIH_IBFE */ "ibfe", + /* WINED3DSIH_IEQ */ "ieq", + /* WINED3DSIH_IF */ "if", + /* WINED3DSIH_IFC */ "ifc", + /* WINED3DSIH_IGE */ "ige", + /* WINED3DSIH_ILT */ "ilt", + /* WINED3DSIH_IMAD */ "imad", + /* WINED3DSIH_IMAX */ "imax", + /* WINED3DSIH_IMIN */ "imin", + /* WINED3DSIH_IMM_ATOMIC_ALLOC */ "imm_atomic_alloc", + /* WINED3DSIH_IMM_ATOMIC_AND */ "imm_atomic_and", + /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ "imm_atomic_cmp_exch", + /* WINED3DSIH_IMM_ATOMIC_CONSUME */ "imm_atomic_consume", + /* WINED3DSIH_IMM_ATOMIC_EXCH */ "imm_atomic_exch", + /* WINED3DSIH_IMM_ATOMIC_IADD */ "imm_atomic_iadd", + /* WINED3DSIH_IMM_ATOMIC_IMAX */ "imm_atomic_imax", + /* WINED3DSIH_IMM_ATOMIC_IMIN */ "imm_atomic_imin", + /* WINED3DSIH_IMM_ATOMIC_OR */ "imm_atomic_or", + /* WINED3DSIH_IMM_ATOMIC_UMAX */ "imm_atomic_umax", + /* WINED3DSIH_IMM_ATOMIC_UMIN */ "imm_atomic_umin", + /* WINED3DSIH_IMM_ATOMIC_XOR */ "imm_atomic_xor", + /* WINED3DSIH_IMUL */ "imul", + /* WINED3DSIH_INE */ "ine", + /* WINED3DSIH_INEG */ "ineg", + /* WINED3DSIH_ISHL */ "ishl", + /* WINED3DSIH_ISHR */ "ishr", + /* WINED3DSIH_ITOF */ "itof", + /* WINED3DSIH_LABEL */ "label", + /* WINED3DSIH_LD */ "ld", + /* WINED3DSIH_LD2DMS */ "ld2dms", + /* WINED3DSIH_LD_RAW */ "ld_raw", + /* WINED3DSIH_LD_STRUCTURED */ "ld_structured", + /* WINED3DSIH_LD_UAV_TYPED */ "ld_uav_typed", + /* WINED3DSIH_LIT */ "lit", + /* WINED3DSIH_LOD */ "lod", + /* WINED3DSIH_LOG */ "log", + /* WINED3DSIH_LOGP */ "logp", + /* WINED3DSIH_LOOP */ "loop", + /* WINED3DSIH_LRP */ "lrp", + /* WINED3DSIH_LT */ "lt", + /* WINED3DSIH_M3x2 */ "m3x2", + /* WINED3DSIH_M3x3 */ "m3x3", + /* WINED3DSIH_M3x4 */ "m3x4", + /* WINED3DSIH_M4x3 */ "m4x3", + /* WINED3DSIH_M4x4 */ "m4x4", + /* WINED3DSIH_MAD */ "mad", + /* WINED3DSIH_MAX */ "max", + /* WINED3DSIH_MIN */ "min", + /* WINED3DSIH_MOV */ "mov", + /* WINED3DSIH_MOVA */ "mova", + /* WINED3DSIH_MOVC */ "movc", + /* WINED3DSIH_MUL */ "mul", + /* WINED3DSIH_NE */ "ne", + /* WINED3DSIH_NOP */ "nop", + /* WINED3DSIH_NOT */ "not", + /* WINED3DSIH_NRM */ "nrm", + /* WINED3DSIH_OR */ "or", + /* WINED3DSIH_PHASE */ "phase", + /* WINED3DSIH_POW */ "pow", + /* WINED3DSIH_RCP */ "rcp", + /* WINED3DSIH_REP */ "rep", + /* WINED3DSIH_RESINFO */ "resinfo", + /* WINED3DSIH_RET */ "ret", + /* WINED3DSIH_RETP */ "retp", + /* WINED3DSIH_ROUND_NE */ "round_ne", + /* WINED3DSIH_ROUND_NI */ "round_ni", + /* WINED3DSIH_ROUND_PI */ "round_pi", + /* WINED3DSIH_ROUND_Z */ "round_z", + /* WINED3DSIH_RSQ */ "rsq", + /* WINED3DSIH_SAMPLE */ "sample", + /* WINED3DSIH_SAMPLE_B */ "sample_b", + /* WINED3DSIH_SAMPLE_C */ "sample_c", + /* WINED3DSIH_SAMPLE_C_LZ */ "sample_c_lz", + /* WINED3DSIH_SAMPLE_GRAD */ "sample_d", + /* WINED3DSIH_SAMPLE_INFO */ "sample_info", + /* WINED3DSIH_SAMPLE_LOD */ "sample_l", + /* WINED3DSIH_SAMPLE_POS */ "sample_pos", + /* WINED3DSIH_SETP */ "setp", + /* WINED3DSIH_SGE */ "sge", + /* WINED3DSIH_SGN */ "sgn", + /* WINED3DSIH_SINCOS */ "sincos", + /* WINED3DSIH_SLT */ "slt", + /* WINED3DSIH_SQRT */ "sqrt", + /* WINED3DSIH_STORE_RAW */ "store_raw", + /* WINED3DSIH_STORE_STRUCTURED */ "store_structured", + /* WINED3DSIH_STORE_UAV_TYPED */ "store_uav_typed", + /* WINED3DSIH_SUB */ "sub", + /* WINED3DSIH_SWAPC */ "swapc", + /* WINED3DSIH_SWITCH */ "switch", + /* WINED3DSIH_SYNC */ "sync", + /* WINED3DSIH_TEX */ "texld", + /* WINED3DSIH_TEXBEM */ "texbem", + /* WINED3DSIH_TEXBEML */ "texbeml", + /* WINED3DSIH_TEXCOORD */ "texcrd", + /* WINED3DSIH_TEXDEPTH */ "texdepth", + /* WINED3DSIH_TEXDP3 */ "texdp3", + /* WINED3DSIH_TEXDP3TEX */ "texdp3tex", + /* WINED3DSIH_TEXKILL */ "texkill", + /* WINED3DSIH_TEXLDD */ "texldd", + /* WINED3DSIH_TEXLDL */ "texldl", + /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth", + /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad", + /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex", + /* WINED3DSIH_TEXM3x3 */ "texm3x3", + /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff", + /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad", + /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec", + /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex", + /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec", + /* WINED3DSIH_TEXREG2AR */ "texreg2ar", + /* WINED3DSIH_TEXREG2GB */ "texreg2gb", + /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb", + /* WINED3DSIH_UBFE */ "ubfe", + /* WINED3DSIH_UDIV */ "udiv", + /* WINED3DSIH_UGE */ "uge", + /* WINED3DSIH_ULT */ "ult", + /* WINED3DSIH_UMAX */ "umax", + /* WINED3DSIH_UMIN */ "umin", + /* WINED3DSIH_UMUL */ "umul", + /* WINED3DSIH_USHR */ "ushr", + /* WINED3DSIH_UTOF */ "utof", + /* WINED3DSIH_XOR */ "xor", }; static const char * const semantic_names[] = @@ -197,16 +292,33 @@ static const char * const semantic_names[] = static const struct { - enum wined3d_sysval_semantic sysval_semantic; + enum wined3d_shader_input_sysval_semantic sysval_semantic; const char *sysval_name; } -sysval_semantic_names[] = +shader_input_sysval_semantic_names[] = { - {WINED3D_SV_POSITION, "SV_Position"}, - {WINED3D_SV_INSTANCEID, "SV_InstanceID"}, - {WINED3D_SV_PRIMITIVEID, "SV_PrimitiveID"}, - {WINED3D_SV_ISFRONTFACE, "SV_IsFrontFace"}, - {WINED3D_SV_SAMPLEINDEX, "SV_SampleIndex"}, + {WINED3D_SIV_POSITION, "position"}, + {WINED3D_SIV_CLIP_DISTANCE, "clip_distance"}, + {WINED3D_SIV_CULL_DISTANCE, "cull_distance"}, + {WINED3D_SIV_RENDER_TARGET_ARRAY_INDEX, "render_target_array_index"}, + {WINED3D_SIV_VIEWPORT_ARRAY_INDEX, "viewport_array_index"}, + {WINED3D_SIV_VERTEX_ID, "vertex_id"}, + {WINED3D_SIV_INSTANCE_ID, "instance_id"}, + {WINED3D_SIV_PRIMITIVE_ID, "primitive_id"}, + {WINED3D_SIV_IS_FRONT_FACE, "is_front_face"}, + {WINED3D_SIV_SAMPLE_INDEX, "sample_index"}, + {WINED3D_SIV_QUAD_U0_TESS_FACTOR, "finalQuadUeq0EdgeTessFactor"}, + {WINED3D_SIV_QUAD_V0_TESS_FACTOR, "finalQuadVeq0EdgeTessFactor"}, + {WINED3D_SIV_QUAD_U1_TESS_FACTOR, "finalQuadUeq1EdgeTessFactor"}, + {WINED3D_SIV_QUAD_V1_TESS_FACTOR, "finalQuadVeq1EdgeTessFactor"}, + {WINED3D_SIV_QUAD_U_INNER_TESS_FACTOR, "finalQuadUInsideTessFactor"}, + {WINED3D_SIV_QUAD_V_INNER_TESS_FACTOR, "finalQuadVInsideTessFactor"}, + {WINED3D_SIV_TRIANGLE_U_TESS_FACTOR, "finalTriUeq0EdgeTessFactor"}, + {WINED3D_SIV_TRIANGLE_V_TESS_FACTOR, "finalTriVeq0EdgeTessFactor"}, + {WINED3D_SIV_TRIANGLE_W_TESS_FACTOR, "finalTriWeq0EdgeTessFactor"}, + {WINED3D_SIV_TRIANGLE_INNER_TESS_FACTOR, "finalTriInsideTessFactor"}, + {WINED3D_SIV_LINE_DETAIL_TESS_FACTOR, "finalLineDetailTessFactor"}, + {WINED3D_SIV_LINE_DENSITY_TESS_FACTOR, "finalLineDensityTessFactor"}, }; static void shader_dump_src_param(struct wined3d_string_buffer *buffer, @@ -214,7 +326,7 @@ static void shader_dump_src_param(struct wined3d_string_buffer *buffer, const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx) { - if (handler_idx >= sizeof(shader_opcode_names) / sizeof(*shader_opcode_names)) + if (handler_idx >= ARRAY_SIZE(shader_opcode_names)) return wine_dbg_sprintf("UNRECOGNIZED(%#x)", handler_idx); return shader_opcode_names[handler_idx]; @@ -222,7 +334,7 @@ const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HA static const char *shader_semantic_name_from_usage(enum wined3d_decl_usage usage) { - if (usage >= sizeof(semantic_names) / sizeof(*semantic_names)) + if (usage >= ARRAY_SIZE(semantic_names)) { FIXME("Unrecognized usage %#x.\n", usage); return "UNRECOGNIZED"; @@ -235,14 +347,26 @@ static enum wined3d_decl_usage shader_usage_from_semantic_name(const char *name) { unsigned int i; - for (i = 0; i < sizeof(semantic_names) / sizeof(*semantic_names); ++i) + for (i = 0; i < ARRAY_SIZE(semantic_names); ++i) { - if (!strcmp(name, semantic_names[i])) return i; + if (!strcmp(name, semantic_names[i])) + return i; } return ~0U; } +static enum wined3d_sysval_semantic shader_sysval_semantic_from_usage(enum wined3d_decl_usage usage) +{ + switch (usage) + { + case WINED3D_DECL_USAGE_POSITION: + return WINED3D_SV_POSITION; + default: + return 0; + } +} + BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) { return !strcmp(semantic_name, shader_semantic_name_from_usage(usage)); @@ -253,8 +377,9 @@ static void shader_signature_from_semantic(struct wined3d_shader_signature_eleme { e->semantic_name = shader_semantic_name_from_usage(s->usage); e->semantic_idx = s->usage_idx; - e->sysval_semantic = 0; - e->component_type = 0; + e->stream_idx = 0; + e->sysval_semantic = shader_sysval_semantic_from_usage(s->usage); + e->component_type = WINED3D_TYPE_FLOAT; e->register_idx = s->reg.reg.idx[0].offset; e->mask = s->reg.write_mask; } @@ -264,27 +389,25 @@ static void shader_signature_from_usage(struct wined3d_shader_signature_element { e->semantic_name = shader_semantic_name_from_usage(usage); e->semantic_idx = usage_idx; - e->sysval_semantic = 0; - e->component_type = 0; + e->stream_idx = 0; + e->sysval_semantic = shader_sysval_semantic_from_usage(usage); + e->component_type = WINED3D_TYPE_FLOAT; e->register_idx = reg_idx; e->mask = write_mask; } -static const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token) +static const struct wined3d_shader_frontend *shader_select_frontend(enum wined3d_shader_byte_code_format format) { - switch (version_token >> 16) + switch (format) { - case WINED3D_SM1_VS: - case WINED3D_SM1_PS: + case WINED3D_SHADER_BYTE_CODE_FORMAT_SM1: return &sm1_shader_frontend; - case WINED3D_SM4_PS: - case WINED3D_SM4_VS: - case WINED3D_SM4_GS: + case WINED3D_SHADER_BYTE_CODE_FORMAT_SM4: return &sm4_shader_frontend; default: - FIXME("Unrecognised version token %#x\n", version_token); + WARN("Invalid byte code format %#x specified.\n", format); return NULL; } } @@ -372,8 +495,7 @@ struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_lis if (!buffer || !string_buffer_init(buffer)) { ERR("Couldn't allocate buffer for temporary string.\n"); - if (buffer) - HeapFree(GetProcessHeap(), 0, buffer); + HeapFree(GetProcessHeap(), 0, buffer); return NULL; } } @@ -480,14 +602,24 @@ static void shader_set_limits(struct wined3d_shader *shader) * shaders to 256. */ {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), { 4, 16, 256, 16, 12, 0}}, {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16, 0, 0, 0, 16, 0}}, - {WINED3D_SHADER_VERSION(5, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, + {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}}, {0} }, + hs_limits[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ + {WINED3D_SHADER_VERSION(5, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 32}}, + }, + ds_limits[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */ + {WINED3D_SHADER_VERSION(5, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 32}}, + }, gs_limits[] = { /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(4, 0), {16, 0, 0, 0, 32, 16}}, - {WINED3D_SHADER_VERSION(5, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 32}}, + {WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 32}}, {0} }, ps_limits[] = @@ -497,9 +629,14 @@ static void shader_set_limits(struct wined3d_shader *shader) {WINED3D_SHADER_VERSION(1, 4), WINED3D_SHADER_VERSION(1, 4), { 6, 0, 8, 0, 0, 0}}, {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 0), {16, 0, 32, 0, 0, 0}}, {WINED3D_SHADER_VERSION(2, 1), WINED3D_SHADER_VERSION(2, 1), {16, 16, 32, 16, 0, 0}}, - {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), {16, 16, 224, 16, 0, 12}}, + {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 0), {16, 16, 224, 16, 0, 10}}, {WINED3D_SHADER_VERSION(4, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 0, 32}}, {0} + }, + cs_limits[] = + { + /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */ + {WINED3D_SHADER_VERSION(5, 0), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 0, 0}}, }; const struct limits_entry *limits_array; DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major, @@ -514,12 +651,21 @@ static void shader_set_limits(struct wined3d_shader *shader) case WINED3D_SHADER_TYPE_VERTEX: limits_array = vs_limits; break; + case WINED3D_SHADER_TYPE_HULL: + limits_array = hs_limits; + break; + case WINED3D_SHADER_TYPE_DOMAIN: + limits_array = ds_limits; + break; case WINED3D_SHADER_TYPE_GEOMETRY: limits_array = gs_limits; break; case WINED3D_SHADER_TYPE_PIXEL: limits_array = ps_limits; break; + case WINED3D_SHADER_TYPE_COMPUTE: + limits_array = cs_limits; + break; } while (limits_array[i].min_version && limits_array[i].min_version <= shader_version) @@ -567,21 +713,14 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w case WINED3DSPR_INPUT: if (shader_type == WINED3D_SHADER_TYPE_PIXEL) { + /* If relative addressing is used, we must assume that all + * registers are used. Even if it is a construct like v3[aL], + * we can't assume that v0, v1 and v2 aren't read because aL + * can be negative. */ if (reg->idx[0].rel_addr) - { - /* If relative addressing is used, we must assume that all registers - * are used. Even if it is a construct like v3[aL], we can't assume - * that v0, v1 and v2 aren't read because aL can be negative */ - unsigned int i; - for (i = 0; i < MAX_REG_INPUT; ++i) - { - shader->u.ps.input_reg_used[i] = TRUE; - } - } + shader->u.ps.input_reg_used = ~0u; else - { - shader->u.ps.input_reg_used[reg->idx[0].offset] = TRUE; - } + shader->u.ps.input_reg_used |= 1u << reg->idx[0].offset; } else reg_maps->input_registers |= 1u << reg->idx[0].offset; @@ -655,6 +794,10 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w reg_maps->rt_mask |= (1u << reg->idx[0].offset); break; + case WINED3DSPR_OUTCONTROLPOINT: + reg_maps->vocp = 1; + break; + default: TRACE("Not recording register of type %#x and [%#x][%#x].\n", reg->type, reg->idx[0].offset, reg->idx[1].offset); @@ -680,7 +823,7 @@ static void shader_record_sample(struct wined3d_shader_reg_maps *reg_maps, if (!map->size) { - if (!(entries = HeapAlloc(GetProcessHeap(), 0, sizeof(*entries) * 4))) + if (!(entries = wined3d_calloc(4, sizeof(*entries)))) { ERR("Failed to allocate sampler map entries.\n"); return; @@ -728,32 +871,118 @@ static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HAN } } +static HRESULT shader_reg_maps_add_tgsm(struct wined3d_shader_reg_maps *reg_maps, + unsigned int register_idx, unsigned int size, unsigned int stride) +{ + struct wined3d_shader_tgsm *tgsm; + + if (register_idx >= MAX_TGSM_REGISTERS) + { + ERR("Invalid TGSM register index %u.\n", register_idx); + return S_OK; + } + if (reg_maps->shader_version.type != WINED3D_SHADER_TYPE_COMPUTE) + { + FIXME("TGSM declarations are allowed only in compute shaders.\n"); + return S_OK; + } + + if (!wined3d_array_reserve((void **)®_maps->tgsm, ®_maps->tgsm_capacity, + register_idx + 1, sizeof(*reg_maps->tgsm))) + return E_OUTOFMEMORY; + + reg_maps->tgsm_count = max(register_idx + 1, reg_maps->tgsm_count); + tgsm = ®_maps->tgsm[register_idx]; + tgsm->size = size; + tgsm->stride = stride; + return S_OK; +} + +static HRESULT shader_record_shader_phase(struct wined3d_shader *shader, + struct wined3d_shader_phase **current_phase, const struct wined3d_shader_instruction *ins, + const DWORD *current_instruction_ptr, const DWORD *previous_instruction_ptr) +{ + struct wined3d_shader_phase *phase; + + if ((phase = *current_phase)) + { + phase->end = previous_instruction_ptr; + *current_phase = NULL; + } + + if (shader->reg_maps.shader_version.type != WINED3D_SHADER_TYPE_HULL) + { + ERR("Unexpected shader type %#x.\n", shader->reg_maps.shader_version.type); + return E_FAIL; + } + + switch (ins->handler_idx) + { + case WINED3DSIH_HS_CONTROL_POINT_PHASE: + if (shader->u.hs.phases.control_point) + { + FIXME("Multiple control point phases.\n"); + HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point); + } + if (!(shader->u.hs.phases.control_point = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(*shader->u.hs.phases.control_point)))) + return E_OUTOFMEMORY; + phase = shader->u.hs.phases.control_point; + break; + case WINED3DSIH_HS_FORK_PHASE: + if (!wined3d_array_reserve((void **)&shader->u.hs.phases.fork, + &shader->u.hs.phases.fork_size, shader->u.hs.phases.fork_count + 1, + sizeof(*shader->u.hs.phases.fork))) + return E_OUTOFMEMORY; + phase = &shader->u.hs.phases.fork[shader->u.hs.phases.fork_count++]; + break; + case WINED3DSIH_HS_JOIN_PHASE: + if (!wined3d_array_reserve((void **)&shader->u.hs.phases.join, + &shader->u.hs.phases.join_size, shader->u.hs.phases.join_count + 1, + sizeof(*shader->u.hs.phases.join))) + return E_OUTOFMEMORY; + phase = &shader->u.hs.phases.join[shader->u.hs.phases.join_count++]; + break; + default: + ERR("Unexpected opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); + return E_FAIL; + } + + phase->start = current_instruction_ptr; + *current_phase = phase; + + return WINED3D_OK; +} + /* Note that this does not count the loop register as an address register. */ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe, struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature, - struct wined3d_shader_signature *output_signature, const DWORD *byte_code, DWORD constf_size) + struct wined3d_shader_signature *output_signature, DWORD constf_size) { struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)]; struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT]; unsigned int cur_loop_depth = 0, max_loop_depth = 0; - void *fe_data = shader->frontend_data; struct wined3d_shader_version shader_version; - const DWORD *ptr = byte_code; + struct wined3d_shader_phase *phase = NULL; + const DWORD *ptr, *prev_ins, *current_ins; + void *fe_data = shader->frontend_data; unsigned int i; + HRESULT hr; memset(reg_maps, 0, sizeof(*reg_maps)); memset(input_signature_elements, 0, sizeof(input_signature_elements)); memset(output_signature_elements, 0, sizeof(output_signature_elements)); reg_maps->min_rel_offset = ~0U; + list_init(®_maps->indexable_temps); fe->shader_read_header(fe_data, &ptr, &shader_version); + prev_ins = current_ins = ptr; reg_maps->shader_version = shader_version; shader_set_limits(shader); - reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*reg_maps->constf) * ((min(shader->limits->constant_float, constf_size) + 31) / 32)); - if (!reg_maps->constf) + if (!(reg_maps->constf = wined3d_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32), + sizeof(*reg_maps->constf)))) { ERR("Failed to allocate constant map memory.\n"); return E_OUTOFMEMORY; @@ -763,18 +992,20 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st { struct wined3d_shader_instruction ins; + current_ins = ptr; /* Fetch opcode. */ fe->shader_read_instruction(fe_data, &ptr, &ins); /* Unhandled opcode, and its parameters. */ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) { - TRACE("Skipping unrecognized instruction.\n"); - continue; + WARN("Encountered unrecognised or invalid instruction.\n"); + return WINED3DERR_INVALIDCALL; } /* Handle declarations. */ - if (ins.handler_idx == WINED3DSIH_DCL) + if (ins.handler_idx == WINED3DSIH_DCL + || ins.handler_idx == WINED3DSIH_DCL_UAV_TYPED) { struct wined3d_shader_semantic *semantic = &ins.declaration.semantic; unsigned int reg_idx = semantic->reg.reg.idx[0].offset; @@ -822,6 +1053,18 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type; break; + case WINED3DSPR_UAV: + if (reg_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV resource index %u.\n", reg_idx); + break; + } + reg_maps->uav_resource_info[reg_idx].type = semantic->resource_type; + reg_maps->uav_resource_info[reg_idx].data_type = semantic->resource_data_type; + if (ins.flags) + FIXME("Ignoring typed UAV flags %#x.\n", ins.flags); + break; + default: TRACE("Not recording DCL register type %#x.\n", semantic->reg.reg.type); break; @@ -835,28 +1078,182 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st else reg_maps->cb_sizes[reg->idx[0].offset] = reg->idx[1].offset; } + else if (ins.handler_idx == WINED3DSIH_DCL_GS_INSTANCES) + { + if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) + shader->u.gs.instance_count = ins.declaration.count; + else + FIXME("Invalid instruction %#x for shader type %#x.\n", + ins.handler_idx, shader_version.type); + } + else if (ins.handler_idx == WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT + || ins.handler_idx == WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) + { + if (phase) + phase->instance_count = ins.declaration.count; + else + FIXME("Instruction %s outside of shader phase.\n", + debug_d3dshaderinstructionhandler(ins.handler_idx)); + } else if (ins.handler_idx == WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) { if (reg_maps->icb) FIXME("Multiple immediate constant buffers.\n"); reg_maps->icb = ins.declaration.icb; } + else if (ins.handler_idx == WINED3DSIH_DCL_INDEXABLE_TEMP) + { + if (phase) + { + FIXME("Indexable temporary registers not supported.\n"); + } + else + { + struct wined3d_shader_indexable_temp *reg; + + if (!(reg = HeapAlloc(GetProcessHeap(), 0, sizeof(*reg)))) + return E_OUTOFMEMORY; + + *reg = ins.declaration.indexable_temp; + list_add_tail(®_maps->indexable_temps, ®->entry); + } + } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE) { if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) - shader->u.gs.input_type = ins.declaration.primitive_type; + shader->u.gs.input_type = ins.declaration.primitive_type.type; else FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); } + else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT) + { + if (shader_version.type == WINED3D_SHADER_TYPE_HULL) + shader->u.hs.output_vertex_count = ins.declaration.count; + else + FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); + } else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY) { if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) - shader->u.gs.output_type = ins.declaration.primitive_type; + shader->u.gs.output_type = ins.declaration.primitive_type.type; else FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); } + else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_RAW) + { + unsigned int reg_idx = ins.declaration.dst.reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", reg_idx); + break; + } + reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER; + reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT; + reg_maps->resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW; + } + else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_STRUCTURED) + { + unsigned int reg_idx = ins.declaration.structured_resource.reg.reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + ERR("Invalid resource index %u.\n", reg_idx); + break; + } + reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER; + reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT; + reg_maps->resource_info[reg_idx].flags = 0; + reg_maps->resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4; + } + else if (ins.handler_idx == WINED3DSIH_DCL_SAMPLER) + { + if (ins.flags & WINED3DSI_SAMPLER_COMPARISON_MODE) + reg_maps->sampler_comparison_mode |= (1u << ins.declaration.dst.reg.idx[0].offset); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TEMPS) + { + if (phase) + phase->temporary_count = ins.declaration.count; + else + reg_maps->temporary_count = ins.declaration.count; + } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_DOMAIN) + { + if (shader_version.type == WINED3D_SHADER_TYPE_DOMAIN) + shader->u.ds.tessellator_domain = ins.declaration.tessellator_domain; + else if (shader_version.type != WINED3D_SHADER_TYPE_HULL) + FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE) + { + if (shader_version.type == WINED3D_SHADER_TYPE_HULL) + shader->u.hs.tessellator_output_primitive = ins.declaration.tessellator_output_primitive; + else + FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_PARTITIONING) + { + if (shader_version.type == WINED3D_SHADER_TYPE_HULL) + shader->u.hs.tessellator_partitioning = ins.declaration.tessellator_partitioning; + else + FIXME("Invalid instruction %#x for shader type %#x.\n", ins.handler_idx, shader_version.type); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TGSM_RAW) + { + if (FAILED(hr = shader_reg_maps_add_tgsm(reg_maps, ins.declaration.tgsm_raw.reg.reg.idx[0].offset, + ins.declaration.tgsm_raw.byte_count / 4, 0))) + return hr; + } + else if (ins.handler_idx == WINED3DSIH_DCL_TGSM_STRUCTURED) + { + unsigned int stride = ins.declaration.tgsm_structured.byte_stride / 4; + unsigned int size = stride * ins.declaration.tgsm_structured.structure_count; + if (FAILED(hr = shader_reg_maps_add_tgsm(reg_maps, + ins.declaration.tgsm_structured.reg.reg.idx[0].offset, size, stride))) + return hr; + } + else if (ins.handler_idx == WINED3DSIH_DCL_THREAD_GROUP) + { + if (shader_version.type == WINED3D_SHADER_TYPE_COMPUTE) + { + shader->u.cs.thread_group_size = ins.declaration.thread_group_size; + } + else + { + FIXME("Invalid instruction %#x for shader type %#x.\n", + ins.handler_idx, shader_version.type); + } + } + else if (ins.handler_idx == WINED3DSIH_DCL_UAV_RAW) + { + unsigned int reg_idx = ins.declaration.dst.reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV resource index %u.\n", reg_idx); + break; + } + if (ins.flags) + FIXME("Ignoring raw UAV flags %#x.\n", ins.flags); + reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER; + reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT; + reg_maps->uav_resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW; + } + else if (ins.handler_idx == WINED3DSIH_DCL_UAV_STRUCTURED) + { + unsigned int reg_idx = ins.declaration.structured_resource.reg.reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(reg_maps->uav_resource_info)) + { + ERR("Invalid UAV resource index %u.\n", reg_idx); + break; + } + if (ins.flags) + FIXME("Ignoring structured UAV flags %#x.\n", ins.flags); + reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER; + reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT; + reg_maps->uav_resource_info[reg_idx].flags = 0; + reg_maps->uav_resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4; + } else if (ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT) { if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) @@ -872,7 +1269,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st if (!lconst) return E_OUTOFMEMORY; lconst->idx = ins.dst[0].reg.idx[0].offset; - memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD)); + memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD)); value = (float *)lconst->value; /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */ @@ -902,7 +1299,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st if (!lconst) return E_OUTOFMEMORY; lconst->idx = ins.dst[0].reg.idx[0].offset; - memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD)); + memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD)); list_add_head(&shader->constantsI, &lconst->entry); reg_maps->local_int_consts |= (1u << lconst->idx); @@ -913,11 +1310,19 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st if (!lconst) return E_OUTOFMEMORY; lconst->idx = ins.dst[0].reg.idx[0].offset; - memcpy(lconst->value, ins.src[0].reg.immconst_data, sizeof(DWORD)); + memcpy(lconst->value, ins.src[0].reg.u.immconst_data, sizeof(DWORD)); list_add_head(&shader->constantsB, &lconst->entry); reg_maps->local_bool_consts |= (1u << lconst->idx); } + /* Handle shader phases. */ + else if (ins.handler_idx == WINED3DSIH_HS_CONTROL_POINT_PHASE + || ins.handler_idx == WINED3DSIH_HS_FORK_PHASE + || ins.handler_idx == WINED3DSIH_HS_JOIN_PHASE) + { + if (FAILED(hr = shader_record_shader_phase(shader, &phase, &ins, current_ins, prev_ins))) + return hr; + } /* For subroutine prototypes. */ else if (ins.handler_idx == WINED3DSIH_LABEL) { @@ -991,12 +1396,22 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } break; - case WINED3DSPR_TEXCRDOUT: + case WINED3DSPR_TEXCRDOUT: /* WINED3DSPR_OUTPUT */ if (shader_version.major >= 3) { + if (idx >= ARRAY_SIZE(reg_maps->u.output_registers_mask)) + { + WARN("Invalid output register index %u.\n", idx); + break; + } reg_maps->u.output_registers_mask[idx] |= ins.dst[i].write_mask; break; } + if (idx >= ARRAY_SIZE(reg_maps->u.texcoord_mask)) + { + WARN("Invalid texcoord index %u.\n", idx); + break; + } reg_maps->u.texcoord_mask[idx] |= ins.dst[i].write_mask; if (reg_maps->output_registers & (1u << idx)) { @@ -1060,6 +1475,12 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st { unsigned int reg_idx = ins.dst[i].reg.idx[0].offset; + if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info)) + { + WARN("Invalid 1.x sampler index %u.\n", reg_idx); + continue; + } + TRACE("Setting fake 2D resource for 1.x pixelshader.\n"); reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT; @@ -1082,9 +1503,57 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } } - if (ins.handler_idx == WINED3DSIH_NRM) reg_maps->usesnrm = 1; - else if (ins.handler_idx == WINED3DSIH_DSY) reg_maps->usesdsy = 1; - else if (ins.handler_idx == WINED3DSIH_DSX) reg_maps->usesdsx = 1; + if (ins.handler_idx == WINED3DSIH_IMM_ATOMIC_ALLOC || ins.handler_idx == WINED3DSIH_IMM_ATOMIC_CONSUME) + { + unsigned int reg_idx = ins.src[0].reg.idx[0].offset; + if (reg_idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + ERR("Invalid UAV index %u.\n", reg_idx); + break; + } + reg_maps->uav_counter_mask |= (1u << reg_idx); + } + else if ((WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR) + || (WINED3DSIH_IMM_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_IMM_ATOMIC_XOR) + || (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_UAV) + || ins.handler_idx == WINED3DSIH_LD_UAV_TYPED + || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_UAV) + || (ins.handler_idx == WINED3DSIH_LD_STRUCTURED && ins.src[2].reg.type == WINED3DSPR_UAV)) + { + unsigned int reg_idx; + if (ins.handler_idx == WINED3DSIH_LD_UAV_TYPED || ins.handler_idx == WINED3DSIH_LD_RAW) + reg_idx = ins.src[1].reg.idx[0].offset; + else if (ins.handler_idx == WINED3DSIH_LD_STRUCTURED) + reg_idx = ins.src[2].reg.idx[0].offset; + else if (WINED3DSIH_ATOMIC_AND <= ins.handler_idx && ins.handler_idx <= WINED3DSIH_ATOMIC_XOR) + reg_idx = ins.dst[0].reg.idx[0].offset; + else if (ins.handler_idx == WINED3DSIH_BUFINFO) + reg_idx = ins.src[0].reg.idx[0].offset; + else + reg_idx = ins.dst[1].reg.idx[0].offset; + if (reg_idx >= MAX_UNORDERED_ACCESS_VIEWS) + { + ERR("Invalid UAV index %u.\n", reg_idx); + break; + } + reg_maps->uav_read_mask |= (1u << reg_idx); + } + else if (ins.handler_idx == WINED3DSIH_NRM) + { + reg_maps->usesnrm = 1; + } + else if (ins.handler_idx == WINED3DSIH_DSY + || ins.handler_idx == WINED3DSIH_DSY_COARSE + || ins.handler_idx == WINED3DSIH_DSY_FINE) + { + reg_maps->usesdsy = 1; + } + else if (ins.handler_idx == WINED3DSIH_DSX + || ins.handler_idx == WINED3DSIH_DSX_COARSE + || ins.handler_idx == WINED3DSIH_DSX_FINE) + { + reg_maps->usesdsx = 1; + } else if (ins.handler_idx == WINED3DSIH_TEXLDD) reg_maps->usestexldd = 1; else if (ins.handler_idx == WINED3DSIH_TEXLDL) reg_maps->usestexldl = 1; else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1; @@ -1103,8 +1572,11 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st { --cur_loop_depth; } - else if (ins.handler_idx == WINED3DSIH_SAMPLE + else if (ins.handler_idx == WINED3DSIH_GATHER4 + || ins.handler_idx == WINED3DSIH_GATHER4_C + || ins.handler_idx == WINED3DSIH_SAMPLE || ins.handler_idx == WINED3DSIH_SAMPLE_B + || ins.handler_idx == WINED3DSIH_SAMPLE_C || ins.handler_idx == WINED3DSIH_SAMPLE_C_LZ || ins.handler_idx == WINED3DSIH_SAMPLE_GRAD || ins.handler_idx == WINED3DSIH_SAMPLE_LOD) @@ -1112,12 +1584,30 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset, ins.src[2].reg.idx[0].offset, reg_maps->sampler_map.count); } + else if (ins.handler_idx == WINED3DSIH_GATHER4_PO + || ins.handler_idx == WINED3DSIH_GATHER4_PO_C) + { + shader_record_sample(reg_maps, ins.src[2].reg.idx[0].offset, + ins.src[3].reg.idx[0].offset, reg_maps->sampler_map.count); + } + else if (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE) + { + shader_record_sample(reg_maps, ins.src[0].reg.idx[0].offset, + WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); + } else if (ins.handler_idx == WINED3DSIH_LD - || ins.handler_idx == WINED3DSIH_RESINFO) + || (ins.handler_idx == WINED3DSIH_LD_RAW && ins.src[1].reg.type == WINED3DSPR_RESOURCE) + || (ins.handler_idx == WINED3DSIH_RESINFO && ins.src[1].reg.type == WINED3DSPR_RESOURCE)) { shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); } + else if (ins.handler_idx == WINED3DSIH_LD_STRUCTURED + && ins.src[2].reg.type == WINED3DSPR_RESOURCE) + { + shader_record_sample(reg_maps, ins.src[2].reg.idx[0].offset, + WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); + } if (ins.predicate) if (!shader_record_register_usage(shader, reg_maps, &ins.predicate->reg, @@ -1152,24 +1642,34 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st } } } + + prev_ins = current_ins; } reg_maps->loop_depth = max_loop_depth; + if (phase) + { + phase->end = prev_ins; + phase = NULL; + } + /* PS before 2.0 don't have explicit color outputs. Instead the value of * R0 is written to the render target. */ if (shader_version.major < 2 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL) reg_maps->rt_mask |= (1u << 0); - shader->functionLength = ((const char *)ptr - (const char *)byte_code); - if (input_signature->elements) { for (i = 0; i < input_signature->element_count; ++i) { reg_maps->input_registers |= 1u << input_signature->elements[i].register_idx; - if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL - && input_signature->elements[i].sysval_semantic == WINED3D_SV_POSITION) - reg_maps->vpos = 1; + if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL) + { + if (input_signature->elements[i].sysval_semantic == WINED3D_SV_POSITION) + reg_maps->vpos = 1; + else if (input_signature->elements[i].sysval_semantic == WINED3D_SV_IS_FRONT_FACE) + reg_maps->usesfacing = 1; + } } } else if (!input_signature->elements && reg_maps->input_registers) @@ -1178,7 +1678,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st struct wined3d_shader_signature_element *e; unsigned int i; - if (!(input_signature->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*input_signature->elements) * count))) + if (!(input_signature->elements = wined3d_calloc(count, sizeof(*input_signature->elements)))) return E_OUTOFMEMORY; input_signature->element_count = count; @@ -1204,7 +1704,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st unsigned int count = wined3d_popcount(reg_maps->output_registers); struct wined3d_shader_signature_element *e; - if (!(output_signature->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*output_signature->elements) * count))) + if (!(output_signature->elements = wined3d_calloc(count, sizeof(*output_signature->elements)))) return E_OUTOFMEMORY; output_signature->element_count = count; @@ -1220,6 +1720,20 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st return WINED3D_OK; } +static void shader_cleanup_reg_maps(struct wined3d_shader_reg_maps *reg_maps) +{ + struct wined3d_shader_indexable_temp *reg, *reg_next; + + HeapFree(GetProcessHeap(), 0, reg_maps->constf); + HeapFree(GetProcessHeap(), 0, reg_maps->sampler_map.entries); + + LIST_FOR_EACH_ENTRY_SAFE(reg, reg_next, ®_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry) + HeapFree(GetProcessHeap(), 0, reg); + list_init(®_maps->indexable_temps); + + HeapFree(GetProcessHeap(), 0, reg_maps->tgsm); +} + unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max) { DWORD map = 1u << max; @@ -1249,24 +1763,126 @@ static void shader_dump_global_flags(struct wined3d_string_buffer *buffer, DWORD shader_addline(buffer, "unknown_flags(%#x)", global_flags); } -static void shader_dump_sysval_semantic(struct wined3d_string_buffer *buffer, enum wined3d_sysval_semantic semantic) +static void shader_dump_sync_flags(struct wined3d_string_buffer *buffer, DWORD sync_flags) +{ + if (sync_flags & WINED3DSSF_GROUP_SHARED_MEMORY) + { + shader_addline(buffer, "_g"); + sync_flags &= ~WINED3DSSF_GROUP_SHARED_MEMORY; + } + if (sync_flags & WINED3DSSF_THREAD_GROUP) + { + shader_addline(buffer, "_t"); + sync_flags &= ~WINED3DSSF_THREAD_GROUP; + } + + if (sync_flags) + shader_addline(buffer, "_unknown_flags(%#x)", sync_flags); +} + +static void shader_dump_uav_flags(struct wined3d_string_buffer *buffer, DWORD uav_flags) +{ + if (uav_flags & WINED3DSUF_GLOBALLY_COHERENT) + { + shader_addline(buffer, "_glc"); + uav_flags &= ~WINED3DSUF_GLOBALLY_COHERENT; + } + if (uav_flags & WINED3DSUF_ORDER_PRESERVING_COUNTER) + { + shader_addline(buffer, "_opc"); + uav_flags &= ~WINED3DSUF_ORDER_PRESERVING_COUNTER; + } + + if (uav_flags) + shader_addline(buffer, "_unknown_flags(%#x)", uav_flags); +} + +static void shader_dump_tessellator_domain(struct wined3d_string_buffer *buffer, + enum wined3d_tessellator_domain domain) +{ + switch (domain) + { + case WINED3D_TESSELLATOR_DOMAIN_LINE: + shader_addline(buffer, "line"); + break; + case WINED3D_TESSELLATOR_DOMAIN_TRIANGLE: + shader_addline(buffer, "triangle"); + break; + case WINED3D_TESSELLATOR_DOMAIN_QUAD: + shader_addline(buffer, "quad"); + break; + default: + shader_addline(buffer, "unknown_tessellator_domain(%#x)", domain); + break; + } +} + +static void shader_dump_tessellator_output_primitive(struct wined3d_string_buffer *buffer, + enum wined3d_tessellator_output_primitive output_primitive) +{ + switch (output_primitive) + { + case WINED3D_TESSELLATOR_OUTPUT_POINT: + shader_addline(buffer, "point"); + break; + case WINED3D_TESSELLATOR_OUTPUT_LINE: + shader_addline(buffer, "line"); + break; + case WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CW: + shader_addline(buffer, "triangle_cw"); + break; + case WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW: + shader_addline(buffer, "triangle_ccw"); + break; + default: + shader_addline(buffer, "unknown_tessellator_output_primitive(%#x)", output_primitive); + break; + } +} + +static void shader_dump_tessellator_partitioning(struct wined3d_string_buffer *buffer, + enum wined3d_tessellator_partitioning partitioning) +{ + switch (partitioning) + { + case WINED3D_TESSELLATOR_PARTITIONING_INTEGER: + shader_addline(buffer, "integer"); + break; + case WINED3D_TESSELLATOR_PARTITIONING_POW2: + shader_addline(buffer, "pow2"); + break; + case WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: + shader_addline(buffer, "fractional_odd"); + break; + case WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: + shader_addline(buffer, "fractional_even"); + break; + default: + shader_addline(buffer, "unknown_tessellator_partitioning(%#x)", partitioning); + break; + } +} + +static void shader_dump_shader_input_sysval_semantic(struct wined3d_string_buffer *buffer, + enum wined3d_shader_input_sysval_semantic semantic) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(sysval_semantic_names); ++i) + for (i = 0; i < ARRAY_SIZE(shader_input_sysval_semantic_names); ++i) { - if (sysval_semantic_names[i].sysval_semantic == semantic) + if (shader_input_sysval_semantic_names[i].sysval_semantic == semantic) { - shader_addline(buffer, "%s", sysval_semantic_names[i].sysval_name); + shader_addline(buffer, "%s", shader_input_sysval_semantic_names[i].sysval_name); return; } } - shader_addline(buffer, "unknown_sysval_semantic(%#x)", semantic); + shader_addline(buffer, "unknown_shader_input_sysval_semantic(%#x)", semantic); } static void shader_dump_decl_usage(struct wined3d_string_buffer *buffer, - const struct wined3d_shader_semantic *semantic, const struct wined3d_shader_version *shader_version) + const struct wined3d_shader_semantic *semantic, unsigned int flags, + const struct wined3d_shader_version *shader_version) { shader_addline(buffer, "dcl"); @@ -1291,9 +1907,12 @@ static void shader_dump_decl_usage(struct wined3d_string_buffer *buffer, break; } } - else if (semantic->reg.reg.type == WINED3DSPR_RESOURCE) + else if (semantic->reg.reg.type == WINED3DSPR_RESOURCE || semantic->reg.reg.type == WINED3DSPR_UAV) { - shader_addline(buffer, "_resource_"); + if (semantic->reg.reg.type == WINED3DSPR_RESOURCE) + shader_addline(buffer, "_resource_"); + else + shader_addline(buffer, "_uav_"); switch (semantic->resource_type) { case WINED3D_SHADER_RESOURCE_BUFFER: @@ -1332,10 +1951,16 @@ static void shader_dump_decl_usage(struct wined3d_string_buffer *buffer, shader_addline(buffer, "texture2dmsarray"); break; + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY: + shader_addline(buffer, "texturecubearray"); + break; + default: shader_addline(buffer, "unknown"); break; } + if (semantic->reg.reg.type == WINED3DSPR_UAV) + shader_dump_uav_flags(buffer, flags); switch (semantic->resource_data_type) { case WINED3D_DATA_FLOAT: @@ -1434,7 +2059,7 @@ static void shader_dump_decl_usage(struct wined3d_string_buffer *buffer, default: shader_addline(buffer, "", semantic->usage); - FIXME("unknown_semantics(0x%08x)", semantic->usage); + FIXME("Unrecognised semantic usage %#x.\n", semantic->usage); } } } @@ -1553,6 +2178,86 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, shader_addline(buffer, "t"); break; + case WINED3DSPR_UAV: + shader_addline(buffer, "u"); + break; + + case WINED3DSPR_OUTPOINTID: + shader_addline(buffer, "vOutputControlPointID"); + break; + + case WINED3DSPR_FORKINSTID: + shader_addline(buffer, "vForkInstanceId"); + break; + + case WINED3DSPR_JOININSTID: + shader_addline(buffer, "vJoinInstanceId"); + break; + + case WINED3DSPR_INCONTROLPOINT: + shader_addline(buffer, "vicp"); + break; + + case WINED3DSPR_OUTCONTROLPOINT: + shader_addline(buffer, "vocp"); + break; + + case WINED3DSPR_PATCHCONST: + shader_addline(buffer, "vpc"); + break; + + case WINED3DSPR_TESSCOORD: + shader_addline(buffer, "vDomainLocation"); + break; + + case WINED3DSPR_GROUPSHAREDMEM: + shader_addline(buffer, "g"); + break; + + case WINED3DSPR_THREADID: + shader_addline(buffer, "vThreadID"); + break; + + case WINED3DSPR_THREADGROUPID: + shader_addline(buffer, "vThreadGroupID"); + break; + + case WINED3DSPR_LOCALTHREADID: + shader_addline(buffer, "vThreadIDInGroup"); + break; + + case WINED3DSPR_LOCALTHREADINDEX: + shader_addline(buffer, "vThreadIDInGroupFlattened"); + break; + + case WINED3DSPR_IDXTEMP: + shader_addline(buffer, "x"); + break; + + case WINED3DSPR_STREAM: + shader_addline(buffer, "m"); + break; + + case WINED3DSPR_FUNCTIONBODY: + shader_addline(buffer, "fb"); + break; + + case WINED3DSPR_FUNCTIONPOINTER: + shader_addline(buffer, "fp"); + break; + + case WINED3DSPR_COVERAGE: + shader_addline(buffer, "vCoverage"); + break; + + case WINED3DSPR_SAMPLEMASK: + shader_addline(buffer, "oMask"); + break; + + case WINED3DSPR_GSINSTID: + shader_addline(buffer, "vGSInstanceID"); + break; + default: shader_addline(buffer, "", reg->type); break; @@ -1567,15 +2272,15 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, switch (reg->data_type) { case WINED3D_DATA_FLOAT: - shader_addline(buffer, "%.8e", *(const float *)reg->immconst_data); + shader_addline(buffer, "%.8e", *(const float *)reg->u.immconst_data); break; case WINED3D_DATA_INT: - shader_addline(buffer, "%d", reg->immconst_data[0]); + shader_addline(buffer, "%d", reg->u.immconst_data[0]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: - shader_addline(buffer, "%u", reg->immconst_data[0]); + shader_addline(buffer, "%u", reg->u.immconst_data[0]); break; default: shader_addline(buffer, "", reg->data_type); @@ -1588,20 +2293,20 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, { case WINED3D_DATA_FLOAT: shader_addline(buffer, "%.8e, %.8e, %.8e, %.8e", - *(const float *)®->immconst_data[0], *(const float *)®->immconst_data[1], - *(const float *)®->immconst_data[2], *(const float *)®->immconst_data[3]); + *(const float *)®->u.immconst_data[0], *(const float *)®->u.immconst_data[1], + *(const float *)®->u.immconst_data[2], *(const float *)®->u.immconst_data[3]); break; case WINED3D_DATA_INT: shader_addline(buffer, "%d, %d, %d, %d", - reg->immconst_data[0], reg->immconst_data[1], - reg->immconst_data[2], reg->immconst_data[3]); + reg->u.immconst_data[0], reg->u.immconst_data[1], + reg->u.immconst_data[2], reg->u.immconst_data[3]); break; case WINED3D_DATA_RESOURCE: case WINED3D_DATA_SAMPLER: case WINED3D_DATA_UINT: shader_addline(buffer, "%u, %u, %u, %u", - reg->immconst_data[0], reg->immconst_data[1], - reg->immconst_data[2], reg->immconst_data[3]); + reg->u.immconst_data[0], reg->u.immconst_data[1], + reg->u.immconst_data[2], reg->u.immconst_data[3]); break; default: shader_addline(buffer, "", reg->data_type); @@ -1640,6 +2345,9 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer, shader_addline(buffer, "%u]", reg->idx[1].offset); } } + + if (reg->type == WINED3DSPR_FUNCTIONPOINTER) + shader_addline(buffer, "[%u]", reg->u.fp_body_idx); } } @@ -1729,38 +2437,41 @@ static void shader_dump_src_param(struct wined3d_string_buffer *buffer, } } -/* Shared code in order to generate the bulk of the shader string. - * NOTE: A description of how to parse tokens can be found on MSDN. */ -void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, - const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) +/* Shared code in order to generate the bulk of the shader string. */ +HRESULT shader_generate_code(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, + const struct wined3d_shader_reg_maps *reg_maps, void *backend_ctx, + const DWORD *start, const DWORD *end) { struct wined3d_device *device = shader->device; const struct wined3d_shader_frontend *fe = shader->frontend; void *fe_data = shader->frontend_data; struct wined3d_shader_version shader_version; - struct wined3d_shader_loop_state loop_state; + struct wined3d_shader_parser_state state; struct wined3d_shader_instruction ins; struct wined3d_shader_tex_mx tex_mx; struct wined3d_shader_context ctx; - const DWORD *ptr = byte_code; + const DWORD *ptr; /* Initialize current parsing state. */ tex_mx.current_row = 0; - loop_state.current_depth = 0; - loop_state.current_reg = 0; + state.current_loop_depth = 0; + state.current_loop_reg = 0; + state.in_subroutine = FALSE; ctx.shader = shader; ctx.gl_info = &device->adapter->gl_info; ctx.reg_maps = reg_maps; ctx.buffer = buffer; ctx.tex_mx = &tex_mx; - ctx.loop_state = &loop_state; + ctx.state = &state; ctx.backend_data = backend_ctx; ins.ctx = &ctx; fe->shader_read_header(fe_data, &ptr, &shader_version); + if (start) + ptr = start; - while (!fe->shader_is_end(fe_data, &ptr)) + while (!fe->shader_is_end(fe_data, &ptr) && ptr != end) { /* Read opcode. */ fe->shader_read_instruction(fe_data, &ptr, &ins); @@ -1768,8 +2479,8 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st /* Unknown opcode and its parameters. */ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) { - TRACE("Skipping unrecognized instruction.\n"); - continue; + WARN("Encountered unrecognised or invalid instruction.\n"); + return WINED3DERR_INVALIDCALL; } if (ins.predicate) @@ -1778,6 +2489,8 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st /* Call appropriate function for output target */ device->shader_backend->shader_handle_instruction(&ins); } + + return WINED3D_OK; } static void shader_dump_ins_modifiers(struct wined3d_string_buffer *buffer, @@ -1802,13 +2515,13 @@ static void shader_dump_ins_modifiers(struct wined3d_string_buffer *buffer, if (mmask & WINED3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid"); mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID); - if (mmask) FIXME("_unrecognized_modifier(%#x)", mmask); + if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask); } static void shader_dump_primitive_type(struct wined3d_string_buffer *buffer, - enum wined3d_primitive_type primitive_type) + const struct wined3d_shader_primitive_type *primitive_type) { - switch (primitive_type) + switch (primitive_type->type) { case WINED3D_PT_UNDEFINED: shader_addline(buffer, "undefined"); @@ -1843,8 +2556,11 @@ static void shader_dump_primitive_type(struct wined3d_string_buffer *buffer, case WINED3D_PT_TRIANGLESTRIP_ADJ: shader_addline(buffer, "trianglestrip_adj"); break; + case WINED3D_PT_PATCH: + shader_addline(buffer, "patch%u", primitive_type->patch_vertex_count); + break; default: - shader_addline(buffer, "", primitive_type); + shader_addline(buffer, "", primitive_type->type); break; } } @@ -1881,13 +2597,13 @@ static void shader_dump_interpolation_mode(struct wined3d_string_buffer *buffer, } } -static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *byte_code) +static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data) { struct wined3d_shader_version shader_version; struct wined3d_string_buffer buffer; - const DWORD *ptr = byte_code; const char *type_prefix; const char *p, *q; + const DWORD *ptr; DWORD i; if (!string_buffer_init(&buffer)) @@ -1896,16 +2612,24 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe return; } - TRACE("Parsing %p.\n", byte_code); - fe->shader_read_header(fe_data, &ptr, &shader_version); + TRACE("Parsing %p.\n", ptr); + switch (shader_version.type) { case WINED3D_SHADER_TYPE_VERTEX: type_prefix = "vs"; break; + case WINED3D_SHADER_TYPE_HULL: + type_prefix = "hs"; + break; + + case WINED3D_SHADER_TYPE_DOMAIN: + type_prefix = "ds"; + break; + case WINED3D_SHADER_TYPE_GEOMETRY: type_prefix = "gs"; break; @@ -1914,6 +2638,10 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe type_prefix = "ps"; break; + case WINED3D_SHADER_TYPE_COMPUTE: + type_prefix = "cs"; + break; + default: FIXME("Unhandled shader type %#x.\n", shader_version.type); type_prefix = "unknown"; @@ -1934,9 +2662,9 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe continue; } - if (ins.handler_idx == WINED3DSIH_DCL) + if (ins.handler_idx == WINED3DSIH_DCL || ins.handler_idx == WINED3DSIH_DCL_UAV_TYPED) { - shader_dump_decl_usage(&buffer, &ins.declaration.semantic, &shader_version); + shader_dump_decl_usage(&buffer, &ins.declaration.semantic, ins.flags, &shader_version); shader_dump_ins_modifiers(&buffer, &ins.declaration.semantic.reg); shader_addline(&buffer, " "); shader_dump_dst_param(&buffer, &ins.declaration.semantic.reg, &shader_version); @@ -1948,15 +2676,30 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe shader_addline(&buffer, ", %s", ins.flags & WINED3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed"); } + else if (ins.handler_idx == WINED3DSIH_DCL_FUNCTION_BODY) + { + shader_addline(&buffer, "%s fb%u", + shader_opcode_names[ins.handler_idx], ins.declaration.index); + } + else if (ins.handler_idx == WINED3DSIH_DCL_FUNCTION_TABLE) + { + shader_addline(&buffer, "%s ft%u = {...}", + shader_opcode_names[ins.handler_idx], ins.declaration.index); + } else if (ins.handler_idx == WINED3DSIH_DCL_GLOBAL_FLAGS) { shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); shader_dump_global_flags(&buffer, ins.flags); } + else if (ins.handler_idx == WINED3DSIH_DCL_HS_MAX_TESSFACTOR) + { + shader_addline(&buffer, "%s %.8e", shader_opcode_names[ins.handler_idx], + ins.declaration.max_tessellation_factor); + } else if (ins.handler_idx == WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) { shader_addline(&buffer, "%s {\n", shader_opcode_names[ins.handler_idx]); - for (i = 0; i < ins.declaration.icb->element_count / 4; ++i) + for (i = 0; i < ins.declaration.icb->vec4_count; ++i) { shader_addline(&buffer, " {0x%08x, 0x%08x, 0x%08x, 0x%08x},\n", ins.declaration.icb->data[4 * i + 0], @@ -1966,6 +2709,19 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe } shader_addline(&buffer, "}"); } + else if (ins.handler_idx == WINED3DSIH_DCL_INDEX_RANGE) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&buffer, &ins.declaration.index_range.first_register, &shader_version); + shader_addline(&buffer, " %u", ins.declaration.index_range.last_register); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INDEXABLE_TEMP) + { + shader_addline(&buffer, "%s x[%u][%u], %u", shader_opcode_names[ins.handler_idx], + ins.declaration.indexable_temp.register_idx, + ins.declaration.indexable_temp.register_size, + ins.declaration.indexable_temp.component_count); + } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS) { shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); @@ -1981,7 +2737,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); shader_dump_dst_param(&buffer, &ins.declaration.register_semantic.reg, &shader_version); shader_addline(&buffer, ", "); - shader_dump_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic); + shader_dump_shader_input_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic); } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS_SIV) { @@ -1990,7 +2746,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe shader_addline(&buffer, " "); shader_dump_dst_param(&buffer, &ins.declaration.register_semantic.reg, &shader_version); shader_addline(&buffer, ", "); - shader_dump_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic); + shader_dump_shader_input_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic); } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT || ins.handler_idx == WINED3DSIH_DCL_OUTPUT) @@ -2002,7 +2758,24 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe || ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY) { shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); - shader_dump_primitive_type(&buffer, ins.declaration.primitive_type); + shader_dump_primitive_type(&buffer, &ins.declaration.primitive_type); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INTERFACE) + { + shader_addline(&buffer, "%s fp[%u][%u][%u] = {...}", + shader_opcode_names[ins.handler_idx], ins.declaration.fp.index, + ins.declaration.fp.array_size, ins.declaration.fp.body_count); + } + else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_RAW) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version); + } + else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_STRUCTURED) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&buffer, &ins.declaration.structured_resource.reg, &shader_version); + shader_addline(&buffer, ", %u", ins.declaration.structured_resource.byte_stride); } else if (ins.handler_idx == WINED3DSIH_DCL_SAMPLER) { @@ -2012,31 +2785,86 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe shader_addline(&buffer, ", comparisonMode"); } else if (ins.handler_idx == WINED3DSIH_DCL_TEMPS + || ins.handler_idx == WINED3DSIH_DCL_GS_INSTANCES + || ins.handler_idx == WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT + || ins.handler_idx == WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT + || ins.handler_idx == WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT + || ins.handler_idx == WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT || ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT) { shader_addline(&buffer, "%s %u", shader_opcode_names[ins.handler_idx], ins.declaration.count); } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_DOMAIN) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_tessellator_domain(&buffer, ins.declaration.tessellator_domain); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_tessellator_output_primitive(&buffer, ins.declaration.tessellator_output_primitive); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TESSELLATOR_PARTITIONING) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_tessellator_partitioning(&buffer, ins.declaration.tessellator_partitioning); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TGSM_RAW) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&buffer, &ins.declaration.tgsm_raw.reg, &shader_version); + shader_addline(&buffer, ", %u", ins.declaration.tgsm_raw.byte_count); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TGSM_STRUCTURED) + { + shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&buffer, &ins.declaration.tgsm_structured.reg, &shader_version); + shader_addline(&buffer, ", %u, %u", ins.declaration.tgsm_structured.byte_stride, + ins.declaration.tgsm_structured.structure_count); + } + else if (ins.handler_idx == WINED3DSIH_DCL_THREAD_GROUP) + { + shader_addline(&buffer, "%s %u, %u, %u", shader_opcode_names[ins.handler_idx], + ins.declaration.thread_group_size.x, + ins.declaration.thread_group_size.y, + ins.declaration.thread_group_size.z); + } + else if (ins.handler_idx == WINED3DSIH_DCL_UAV_RAW) + { + shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]); + shader_dump_uav_flags(&buffer, ins.flags); + shader_addline(&buffer, " "); + shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version); + } + else if (ins.handler_idx == WINED3DSIH_DCL_UAV_STRUCTURED) + { + shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]); + shader_dump_uav_flags(&buffer, ins.flags); + shader_addline(&buffer, " "); + shader_dump_dst_param(&buffer, &ins.declaration.structured_resource.reg, &shader_version); + shader_addline(&buffer, ", %u", ins.declaration.structured_resource.byte_stride); + } else if (ins.handler_idx == WINED3DSIH_DEF) { shader_addline(&buffer, "def c%u = %.8e, %.8e, %.8e, %.8e", shader_get_float_offset(ins.dst[0].reg.type, ins.dst[0].reg.idx[0].offset), - *(const float *)&ins.src[0].reg.immconst_data[0], - *(const float *)&ins.src[0].reg.immconst_data[1], - *(const float *)&ins.src[0].reg.immconst_data[2], - *(const float *)&ins.src[0].reg.immconst_data[3]); + *(const float *)&ins.src[0].reg.u.immconst_data[0], + *(const float *)&ins.src[0].reg.u.immconst_data[1], + *(const float *)&ins.src[0].reg.u.immconst_data[2], + *(const float *)&ins.src[0].reg.u.immconst_data[3]); } else if (ins.handler_idx == WINED3DSIH_DEFI) { shader_addline(&buffer, "defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx[0].offset, - ins.src[0].reg.immconst_data[0], - ins.src[0].reg.immconst_data[1], - ins.src[0].reg.immconst_data[2], - ins.src[0].reg.immconst_data[3]); + ins.src[0].reg.u.immconst_data[0], + ins.src[0].reg.u.immconst_data[1], + ins.src[0].reg.u.immconst_data[2], + ins.src[0].reg.u.immconst_data[3]); } else if (ins.handler_idx == WINED3DSIH_DEFB) { shader_addline(&buffer, "defb b%u = %s", - ins.dst[0].reg.idx[0].offset, ins.src[0].reg.immconst_data[0] ? "true" : "false"); + ins.dst[0].reg.idx[0].offset, ins.src[0].reg.u.immconst_data[0] ? "true" : "false"); } else { @@ -2053,7 +2881,19 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]); - if (ins.handler_idx == WINED3DSIH_IFC + if (ins.handler_idx == WINED3DSIH_BREAKP + || ins.handler_idx == WINED3DSIH_CONTINUEP + || ins.handler_idx == WINED3DSIH_IF + || ins.handler_idx == WINED3DSIH_RETP) + { + switch (ins.flags) + { + case WINED3D_SHADER_CONDITIONAL_OP_NZ: shader_addline(&buffer, "_nz"); break; + case WINED3D_SHADER_CONDITIONAL_OP_Z: shader_addline(&buffer, "_z"); break; + default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags); break; + } + } + else if (ins.handler_idx == WINED3DSIH_IFC || ins.handler_idx == WINED3DSIH_BREAKC) { switch (ins.flags) @@ -2073,8 +2913,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe { shader_addline(&buffer, "p"); } - else if (ins.handler_idx == WINED3DSIH_RESINFO - && ins.flags) + else if (ins.handler_idx == WINED3DSIH_RESINFO && ins.flags) { switch (ins.flags) { @@ -2083,6 +2922,21 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags); } } + else if (ins.handler_idx == WINED3DSIH_SAMPLE_INFO && ins.flags) + { + switch (ins.flags) + { + case WINED3DSI_SAMPLE_INFO_UINT: shader_addline(&buffer, "_uint"); break; + default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags); + } + } + else if (ins.handler_idx == WINED3DSIH_SYNC) + { + shader_dump_sync_flags(&buffer, ins.flags); + } + + if (wined3d_shader_instruction_has_texel_offset(&ins)) + shader_addline(&buffer, "(%d,%d,%d)", ins.texel_offset.u, ins.texel_offset.v, ins.texel_offset.w); for (i = 0; i < ins.dst_count; ++i) { @@ -2113,18 +2967,25 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe string_buffer_free(&buffer); } -#if defined(STAGING_CSMT) -void shader_cleanup(struct wined3d_shader *shader) -#else /* STAGING_CSMT */ static void shader_cleanup(struct wined3d_shader *shader) -#endif /* STAGING_CSMT */ { + if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_HULL) + { + HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point); + HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.fork); + HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.join); + } + else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) + { + HeapFree(GetProcessHeap(), 0, shader->u.gs.so_desc.elements); + } + + HeapFree(GetProcessHeap(), 0, shader->patch_constant_signature.elements); HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); HeapFree(GetProcessHeap(), 0, shader->signature_strings); shader->device->shader_backend->shader_destroy(shader); - HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf); - HeapFree(GetProcessHeap(), 0, shader->reg_maps.sampler_map.entries); + shader_cleanup_reg_maps(&shader->reg_maps); HeapFree(GetProcessHeap(), 0, shader->function); shader_delete_constant_list(&shader->constantsF); shader_delete_constant_list(&shader->constantsB); @@ -2143,9 +3004,9 @@ struct shader_none_priv }; static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {} -static void shader_none_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info, - enum wined3d_gl_resource_type tex_type, const SIZE *ds_mask_size) {} -static void shader_none_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) {} +static void shader_none_precompile(void *shader_priv, struct wined3d_shader *shader) {} +static void shader_none_select_compute(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state) {} static void shader_none_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) {} static void shader_none_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) {} static void shader_none_load_constants(void *shader_priv, struct wined3d_context *context, @@ -2176,7 +3037,10 @@ static void shader_none_disable(void *shader_priv, struct wined3d_context *conte context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) - | (1u << WINED3D_SHADER_TYPE_GEOMETRY); + | (1u << WINED3D_SHADER_TYPE_GEOMETRY) + | (1u << WINED3D_SHADER_TYPE_HULL) + | (1u << WINED3D_SHADER_TYPE_DOMAIN) + | (1u << WINED3D_SHADER_TYPE_COMPUTE); } static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, @@ -2234,8 +3098,11 @@ static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct s { /* Set the shader caps to 0 for the none shader backend */ caps->vs_version = 0; + caps->hs_version = 0; + caps->ds_version = 0; caps->gs_version = 0; caps->ps_version = 0; + caps->cs_version = 0; caps->vs_uniform_count = 0; caps->ps_uniform_count = 0; caps->ps_1x_max_value = 0.0f; @@ -2260,10 +3127,10 @@ static BOOL shader_none_has_ffp_proj_control(void *shader_priv) const struct wined3d_shader_backend_ops none_shader_backend = { shader_none_handle_instruction, + shader_none_precompile, shader_none_select, + shader_none_select_compute, shader_none_disable, - shader_none_select_depth_blt, - shader_none_deselect_depth_blt, shader_none_update_float_vertex_constants, shader_none_update_float_pixel_constants, shader_none_load_constants, @@ -2278,8 +3145,7 @@ const struct wined3d_shader_backend_ops none_shader_backend = shader_none_has_ffp_proj_control, }; -static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *byte_code, - const struct wined3d_shader_signature *output_signature, DWORD float_const_count, +static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_const_count, enum wined3d_shader_type type, unsigned int max_version) { struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; @@ -2288,23 +3154,12 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b unsigned int backend_version; const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info; - TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u, type %#x, max_version %u.\n", - shader, byte_code, output_signature, float_const_count, type, max_version); + TRACE("shader %p, float_const_count %u, type %#x, max_version %u.\n", + shader, float_const_count, type, max_version); - list_init(&shader->constantsF); - list_init(&shader->constantsB); - list_init(&shader->constantsI); - shader->lconst_inf_or_nan = FALSE; - - fe = shader_select_frontend(*byte_code); - if (!fe) - { - FIXME("Unable to find frontend for shader.\n"); - return WINED3DERR_INVALIDCALL; - } - shader->frontend = fe; - shader->frontend_data = fe->shader_init(byte_code, output_signature); - if (!shader->frontend_data) + fe = shader->frontend; + if (!(shader->frontend_data = fe->shader_init(shader->function, + shader->functionLength, &shader->output_signature))) { FIXME("Failed to initialize frontend.\n"); return WINED3DERR_INVALIDCALL; @@ -2312,11 +3167,11 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b /* First pass: trace shader. */ if (TRACE_ON(d3d_shader)) - shader_trace_init(fe, shader->frontend_data, byte_code); + shader_trace_init(fe, shader->frontend_data); /* Second pass: figure out which registers are used, what the semantics are, etc. */ if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, &shader->input_signature, - &shader->output_signature, byte_code, float_const_count))) + &shader->output_signature, float_const_count))) return hr; if (reg_maps->shader_version.type != type) @@ -2334,14 +3189,23 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b case WINED3D_SHADER_TYPE_VERTEX: backend_version = d3d_info->limits.vs_version; break; + case WINED3D_SHADER_TYPE_HULL: + backend_version = d3d_info->limits.hs_version; + break; + case WINED3D_SHADER_TYPE_DOMAIN: + backend_version = d3d_info->limits.ds_version; + break; case WINED3D_SHADER_TYPE_GEOMETRY: backend_version = d3d_info->limits.gs_version; break; case WINED3D_SHADER_TYPE_PIXEL: backend_version = d3d_info->limits.ps_version; break; + case WINED3D_SHADER_TYPE_COMPUTE: + backend_version = d3d_info->limits.cs_version; + break; default: - FIXME("No backend version-checking for this shader type\n"); + FIXME("No backend version-checking for this shader type.\n"); backend_version = 0; } if (reg_maps->shader_version.major > backend_version) @@ -2351,11 +3215,6 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b return WINED3DERR_INVALIDCALL; } - shader->function = HeapAlloc(GetProcessHeap(), 0, shader->functionLength); - if (!shader->function) - return E_OUTOFMEMORY; - memcpy(shader->function, byte_code, shader->functionLength); - return WINED3D_OK; } @@ -2368,6 +3227,22 @@ ULONG CDECL wined3d_shader_incref(struct wined3d_shader *shader) return refcount; } +static void wined3d_shader_init_object(void *object) +{ + struct wined3d_shader *shader = object; + struct wined3d_device *device = shader->device; + + list_add_head(&device->shaders, &shader->shader_list_entry); + + device->shader_backend->shader_precompile(device->shader_priv, shader); +} + +static void wined3d_shader_destroy_object(void *object) +{ + shader_cleanup(object); + HeapFree(GetProcessHeap(), 0, object); +} + ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) { ULONG refcount = InterlockedDecrement(&shader->ref); @@ -2376,16 +3251,8 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) if (!refcount) { -#if defined(STAGING_CSMT) - const struct wined3d_device *device = shader->device; - shader->parent_ops->wined3d_object_destroyed(shader->parent); - wined3d_cs_emit_shader_cleanup(device->cs, shader); -#else /* STAGING_CSMT */ - shader_cleanup(shader); - shader->parent_ops->wined3d_object_destroyed(shader->parent); - HeapFree(GetProcessHeap(), 0, shader); -#endif /* STAGING_CSMT */ + wined3d_cs_destroy_object(shader->device->cs, wined3d_shader_destroy_object, shader); } return refcount; @@ -2469,11 +3336,23 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3 && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; args->point_size = state->gl_primitive_type == GL_POINTS; args->per_vertex_point_size = shader->reg_maps.point_size; + args->next_shader_type = state->shader[WINED3D_SHADER_TYPE_HULL] ? WINED3D_SHADER_TYPE_HULL + : state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? WINED3D_SHADER_TYPE_GEOMETRY + : WINED3D_SHADER_TYPE_PIXEL; + if (shader->reg_maps.shader_version.major >= 4) + args->next_shader_input_count = state->shader[WINED3D_SHADER_TYPE_HULL] + ? state->shader[WINED3D_SHADER_TYPE_HULL]->limits->packed_input + : state->shader[WINED3D_SHADER_TYPE_GEOMETRY] + ? state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->limits->packed_input + : state->shader[WINED3D_SHADER_TYPE_PIXEL] + ? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input : 0; + else + args->next_shader_input_count = 0; args->swizzle_map = swizzle_map; if (d3d_info->emulated_flatshading) args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; else - args->flatshading = FALSE; + args->flatshading = 0; } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) @@ -2510,6 +3389,25 @@ BOOL vshader_get_input(const struct wined3d_shader *shader, return FALSE; } +static HRESULT shader_signature_calculate_strings_length(const struct wined3d_shader_signature *signature, + SIZE_T *total) +{ + struct wined3d_shader_signature_element *e; + unsigned int i; + SIZE_T len; + + for (i = 0; i < signature->element_count; ++i) + { + e = &signature->elements[i]; + len = strlen(e->semantic_name); + if (len >= ~(SIZE_T)0 - *total) + return E_OUTOFMEMORY; + + *total += len + 1; + } + return WINED3D_OK; +} + static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst, const struct wined3d_shader_signature *src, char **signature_strings) { @@ -2518,10 +3416,13 @@ static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst, SIZE_T len; char *ptr; + if (!src->element_count) + return WINED3D_OK; + ptr = *signature_strings; dst->element_count = src->element_count; - if (!(dst->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst->elements) * dst->element_count))) + if (!(dst->elements = wined3d_calloc(dst->element_count, sizeof(*dst->elements)))) return E_OUTOFMEMORY; for (i = 0; i < src->element_count; ++i) @@ -2544,77 +3445,114 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device const struct wined3d_shader_desc *desc, DWORD float_const_count, enum wined3d_shader_type type, void *parent, const struct wined3d_parent_ops *parent_ops) { - struct wined3d_shader_signature_element *e; - SIZE_T total, len; - unsigned int i; + size_t byte_code_size; + SIZE_T total; HRESULT hr; char *ptr; + TRACE("byte_code %p, byte_code_size %#lx, format %#x, max_version %#x.\n", + desc->byte_code, (long)desc->byte_code_size, desc->format, desc->max_version); + if (!desc->byte_code) return WINED3DERR_INVALIDCALL; + if (!(shader->frontend = shader_select_frontend(desc->format))) + { + FIXME("Unable to find frontend for shader.\n"); + return WINED3DERR_INVALIDCALL; + } + shader->ref = 1; shader->device = device; shader->parent = parent; shader->parent_ops = parent_ops; total = 0; - if (desc->input_signature) - { - for (i = 0; i < desc->input_signature->element_count; ++i) - { - e = &desc->input_signature->elements[i]; - len = strlen(e->semantic_name); - if (len >= ~(SIZE_T)0 - total) - return E_OUTOFMEMORY; - - total += len + 1; - } - } - if (desc->output_signature) - { - for (i = 0; i < desc->output_signature->element_count; ++i) - { - e = &desc->output_signature->elements[i]; - len = strlen(e->semantic_name); - if (len >= ~(SIZE_T)0 - total) - return E_OUTOFMEMORY; - - total += len + 1; - } - } - if (!(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total))) + if (FAILED(hr = shader_signature_calculate_strings_length(&desc->input_signature, &total))) + return hr; + if (FAILED(hr = shader_signature_calculate_strings_length(&desc->output_signature, &total))) + return hr; + if (FAILED(hr = shader_signature_calculate_strings_length(&desc->patch_constant_signature, &total))) + return hr; + if (total && !(shader->signature_strings = HeapAlloc(GetProcessHeap(), 0, total))) return E_OUTOFMEMORY; ptr = shader->signature_strings; - if (desc->input_signature && FAILED(hr = shader_signature_copy(&shader->input_signature, - desc->input_signature, &ptr))) + if (FAILED(hr = shader_signature_copy(&shader->input_signature, &desc->input_signature, &ptr))) { HeapFree(GetProcessHeap(), 0, shader->signature_strings); return hr; } - if (desc->output_signature && FAILED(hr = shader_signature_copy(&shader->output_signature, - desc->output_signature, &ptr))) + if (FAILED(hr = shader_signature_copy(&shader->output_signature, &desc->output_signature, &ptr))) { HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); HeapFree(GetProcessHeap(), 0, shader->signature_strings); return hr; } + if (FAILED(hr = shader_signature_copy(&shader->patch_constant_signature, &desc->patch_constant_signature, &ptr))) + { + HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); + HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); + HeapFree(GetProcessHeap(), 0, shader->signature_strings); + return hr; + } list_init(&shader->linked_programs); - list_add_head(&device->shaders, &shader->shader_list_entry); + list_init(&shader->constantsF); + list_init(&shader->constantsB); + list_init(&shader->constantsI); + shader->lconst_inf_or_nan = FALSE; + list_init(&shader->reg_maps.indexable_temps); + list_init(&shader->shader_list_entry); - if (FAILED(hr = shader_set_function(shader, desc->byte_code, desc->output_signature, - float_const_count, type, desc->max_version))) + byte_code_size = desc->byte_code_size; + if (byte_code_size == ~(size_t)0) + { + const struct wined3d_shader_frontend *fe = shader->frontend; + struct wined3d_shader_version shader_version; + struct wined3d_shader_instruction ins; + const DWORD *ptr; + void *fe_data; + + if (!(fe_data = fe->shader_init(desc->byte_code, byte_code_size, &shader->output_signature))) + { + WARN("Failed to initialise frontend data.\n"); + shader_cleanup(shader); + return WINED3DERR_INVALIDCALL; + } + + fe->shader_read_header(fe_data, &ptr, &shader_version); + while (!fe->shader_is_end(fe_data, &ptr)) + fe->shader_read_instruction(fe_data, &ptr, &ins); + + fe->shader_free(fe_data); + + byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr); + } + + if (!(shader->function = HeapAlloc(GetProcessHeap(), 0, byte_code_size))) + { + shader_cleanup(shader); + return E_OUTOFMEMORY; + } + memcpy(shader->function, desc->byte_code, byte_code_size); + shader->functionLength = byte_code_size; + + if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version))) { WARN("Failed to set function, hr %#x.\n", hr); shader_cleanup(shader); + return hr; } + shader->load_local_constsF = shader->lconst_inf_or_nan; + + wined3d_cs_init_object(shader->device->cs, wined3d_shader_init_object, shader); + return hr; } -static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_device *device, +static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; @@ -2637,40 +3575,87 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d shader->u.vs.attributes[input->register_idx].usage_idx = input->semantic_idx; } - shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) || - shader->lconst_inf_or_nan; + if (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) + shader->load_local_constsF = TRUE; return WINED3D_OK; } -static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device, +static HRESULT domain_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { + return shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_DOMAIN, parent, parent_ops); +} + +static HRESULT hull_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, + const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + return shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_HULL, parent, parent_ops); +} + +static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, + const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + struct wined3d_stream_output_element *elements = NULL; HRESULT hr; - if (FAILED(hr = shader_init(shader, device, desc, 0, - WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops))) - return hr; + if (so_desc && !(elements = wined3d_calloc(so_desc->element_count, sizeof(*elements)))) + return E_OUTOFMEMORY; - shader->load_local_constsF = shader->lconst_inf_or_nan; + if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops))) + { + HeapFree(GetProcessHeap(), 0, elements); + return hr; + } + + if (so_desc) + { + shader->u.gs.so_desc = *so_desc; + shader->u.gs.so_desc.elements = elements; + memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements)); + } return WINED3D_OK; } +void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + struct ds_compile_args *args, const struct wined3d_context *context) +{ + const struct wined3d_shader *hull_shader = state->shader[WINED3D_SHADER_TYPE_HULL]; + + args->tessellator_output_primitive = hull_shader->u.hs.tessellator_output_primitive; + args->tessellator_partitioning = hull_shader->u.hs.tessellator_partitioning; + + args->output_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? + state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->limits->packed_input : + state->shader[WINED3D_SHADER_TYPE_PIXEL] ? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input + : shader->limits->packed_output; + args->next_shader_type = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ? WINED3D_SHADER_TYPE_GEOMETRY + : WINED3D_SHADER_TYPE_PIXEL; + + args->render_offscreen = context->render_offscreen; + + args->padding = 0; +} + +void find_gs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + struct gs_compile_args *args) +{ + args->output_count = state->shader[WINED3D_SHADER_TYPE_PIXEL] + ? state->shader[WINED3D_SHADER_TYPE_PIXEL]->limits->packed_input : shader->limits->packed_output; +} + void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; + const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_texture *texture; - UINT i; + unsigned int i; memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ -#if defined(STAGING_CSMT) - if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, &state->fb)) -#else /* STAGING_CSMT */ if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb)) -#endif /* STAGING_CSMT */ { static unsigned int warned = 0; @@ -2770,26 +3755,41 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 } } - for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + if (shader->reg_maps.shader_version.major >= 4) { - if (!shader->reg_maps.resource_info[i].type) - continue; - - texture = state->textures[i]; - if (!texture) - { + /* In SM4+ we use dcl_sampler in order to determine if we should use shadow sampler. */ + args->shadow = 0; + for (i = 0 ; i < MAX_FRAGMENT_SAMPLERS; ++i) args->color_fixup[i] = COLOR_FIXUP_IDENTITY; - continue; - } - args->color_fixup[i] = texture->resource.format->color_fixup; - - if (texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW) - args->shadow |= 1u << i; - - /* Flag samplers that need NP2 texcoord fixup. */ - if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) - args->np2_fixup |= (1u << i); + args->np2_fixup = 0; } + else + { + for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) + { + if (!shader->reg_maps.resource_info[i].type) + continue; + + texture = state->textures[i]; + if (!texture) + { + args->color_fixup[i] = COLOR_FIXUP_IDENTITY; + continue; + } + if (can_use_texture_swizzle(gl_info, texture->resource.format)) + args->color_fixup[i] = COLOR_FIXUP_IDENTITY; + else + args->color_fixup[i] = texture->resource.format->color_fixup; + + if (texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW) + args->shadow |= 1u << i; + + /* Flag samplers that need NP2 texcoord fixup. */ + if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) + args->np2_fixup |= (1u << i); + } + } + if (shader->reg_maps.shader_version.major >= 3) { if (position_transformed) @@ -2866,11 +3866,21 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->gl_primitive_type == GL_POINTS; + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + args->alpha_test_func = WINED3D_CMP_ALWAYS - 1; + else + args->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] + ? wined3d_sanitize_cmp_func(state->render_states[WINED3D_RS_ALPHAFUNC]) + : WINED3D_CMP_ALWAYS) - 1; + if (d3d_info->emulated_flatshading) args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + + args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] + ? context->render_offscreen : 0; } -static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device, +static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; @@ -2883,7 +3893,7 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de for (i = 0; i < MAX_REG_INPUT; ++i) { - if (shader->u.ps.input_reg_used[i]) + if (shader->u.ps.input_reg_used & (1u << i)) { ++num_regs_used; highest_reg_used = i; @@ -2893,7 +3903,8 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de /* Don't do any register mapping magic if it is not needed, or if we can't * achieve anything anyway */ if (highest_reg_used < (gl_info->limits.glsl_varyings / 4) - || num_regs_used > (gl_info->limits.glsl_varyings / 4)) + || num_regs_used > (gl_info->limits.glsl_varyings / 4) + || shader->reg_maps.shader_version.major >= 4) { if (num_regs_used > (gl_info->limits.glsl_varyings / 4)) { @@ -2915,14 +3926,12 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de shader->u.ps.declared_in_count = 0; for (i = 0; i < MAX_REG_INPUT; ++i) { - if (shader->u.ps.input_reg_used[i]) + if (shader->u.ps.input_reg_used & (1u << i)) shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++; else shader->u.ps.input_reg_map[i] = ~0U; } } - shader->load_local_constsF = shader->lconst_inf_or_nan; - return WINED3D_OK; } @@ -2957,7 +3966,13 @@ void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_t } } -HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, +static HRESULT compute_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, + const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + return shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_COMPUTE, parent, parent_ops); +} + +HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader) { struct wined3d_shader *object; @@ -2966,11 +3981,61 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", device, desc, parent, parent_ops, shader); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if (!object) + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = geometryshader_init(object, device, desc, parent, parent_ops))) + if (FAILED(hr = compute_shader_init(object, device, desc, parent, parent_ops))) + { + WARN("Failed to initialize compute shader, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created compute shader %p.\n", object); + *shader = object; + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader) +{ + struct wined3d_shader *object; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", + device, desc, parent, parent_ops, shader); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = domain_shader_init(object, device, desc, parent, parent_ops))) + { + WARN("Failed to initialize domain shader, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created domain shader %p.\n", object); + *shader = object; + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + const struct wined3d_stream_output_desc *so_desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader) +{ + struct wined3d_shader *object; + HRESULT hr; + + TRACE("device %p, desc %p, so_desc %p, parent %p, parent_ops %p, shader %p.\n", + device, desc, so_desc, parent, parent_ops, shader); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = geometry_shader_init(object, device, desc, so_desc, parent, parent_ops))) { WARN("Failed to initialize geometry shader, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -2983,6 +4048,31 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru return WINED3D_OK; } +HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader) +{ + struct wined3d_shader *object; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n", + device, desc, parent, parent_ops, shader); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = hull_shader_init(object, device, desc, parent, parent_ops))) + { + WARN("Failed to initialize hull shader, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created hull shader %p.\n", object); + *shader = object; + + return WINED3D_OK; +} + HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader) { @@ -2996,7 +4086,7 @@ HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const stru if (!object) return E_OUTOFMEMORY; - if (FAILED(hr = pixelshader_init(object, device, desc, parent, parent_ops))) + if (FAILED(hr = pixel_shader_init(object, device, desc, parent, parent_ops))) { WARN("Failed to initialize pixel shader, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -3022,7 +4112,7 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru if (!object) return E_OUTOFMEMORY; - if (FAILED(hr = vertexshader_init(object, device, desc, parent, parent_ops))) + if (FAILED(hr = vertex_shader_init(object, device, desc, parent, parent_ops))) { WARN("Failed to initialize vertex shader, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/reactos/dll/directx/wine/wined3d/shader_sm1.c b/reactos/dll/directx/wine/wined3d/shader_sm1.c index 5815184f2a6..983de5875f1 100644 --- a/reactos/dll/directx/wine/wined3d/shader_sm1.c +++ b/reactos/dll/directx/wine/wined3d/shader_sm1.c @@ -199,8 +199,8 @@ enum wined3d_sm1_opcode struct wined3d_sm1_opcode_info { enum wined3d_sm1_opcode opcode; - UINT dst_count; - UINT param_count; + unsigned int dst_count; + unsigned int param_count; enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; DWORD min_version; DWORD max_version; @@ -210,6 +210,7 @@ struct wined3d_sm1_data { struct wined3d_shader_version shader_version; const struct wined3d_sm1_opcode_info *opcode_table; + const DWORD *start; struct wined3d_shader_src_param src_rel_addr[4]; struct wined3d_shader_src_param pred_rel_addr; @@ -395,9 +396,10 @@ static const enum wined3d_shader_resource_type resource_type_table[] = /* Read a parameter opcode from the input stream, * and possibly a relative addressing token. * Return the number of tokens read */ -static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, DWORD *token, DWORD *addr_token) +static unsigned int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, + DWORD *token, DWORD *addr_token) { - UINT count = 1; + unsigned int count = 1; *token = *ptr; @@ -424,15 +426,15 @@ static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *pt return count; } -static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD code) +static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD token) { DWORD shader_version = WINED3D_SHADER_VERSION(priv->shader_version.major, priv->shader_version.minor); const struct wined3d_sm1_opcode_info *opcode_table = priv->opcode_table; - DWORD i = 0; + unsigned int i = 0; while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE) { - if ((code & WINED3D_SM1_OPCODE_MASK) == opcode_table[i].opcode + if ((token & WINED3D_SM1_OPCODE_MASK) == opcode_table[i].opcode && shader_version >= opcode_table[i].min_version && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version)) { @@ -441,19 +443,20 @@ static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wine ++i; } - FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n", - code, code, code & WINED3D_SM1_OPCODE_MASK, shader_version); + FIXME("Unsupported opcode %#x, token 0x%08x, shader version %#x.\n", + token & WINED3D_SM1_OPCODE_MASK, token, shader_version); return NULL; } /* Return the number of parameters to skip for an opcode */ -static int shader_skip_opcode(const struct wined3d_sm1_data *priv, +static unsigned int shader_skip_opcode(const struct wined3d_sm1_data *priv, const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token) { + unsigned int length; /* Shaders >= 2.0 may contain address tokens, but fortunately they * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */ - DWORD length = (opcode_token & WINED3D_SM1_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM1_INSTRUCTION_LENGTH_SHIFT; + length = (opcode_token & WINED3D_SM1_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM1_INSTRUCTION_LENGTH_SHIFT; return (priv->shader_version.major >= 2) ? length : opcode_info->param_count; } @@ -492,10 +495,9 @@ static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_ * Note: This function assumes source or destination token format. * It will not work with specially-formatted tokens like DEF or DCL, * but hopefully those would be recognized */ -static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr) +static unsigned int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr) { - int tokens_read = 0; - int i = 0; + unsigned int tokens_read = 0, i = 0; /* TODO: Think of a good name for 0x80000000 and replace it with a constant */ while (*ptr & 0x80000000) @@ -506,9 +508,10 @@ static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const D tokens_read += shader_get_param(priv, ptr, &token, &addr_token); ptr += tokens_read; - FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token); + FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x.\n", token, addr_token); - if (token & WINED3D_SM1_ADDRESS_MODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr); + if (token & WINED3D_SM1_ADDRESS_MODE_RELATIVE) + shader_parse_src_param(addr_token, NULL, &rel_addr); if (!i) { @@ -522,17 +525,19 @@ static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const D shader_parse_src_param(token, token & WINED3D_SM1_ADDRESS_MODE_RELATIVE ? &rel_addr : NULL, &src); } - FIXME("\n"); ++i; } return tokens_read; } -static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature) +static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size, + const struct wined3d_shader_signature *output_signature) { struct wined3d_sm1_data *priv; BYTE major, minor; + TRACE("Version: 0x%08x.\n", *byte_code); + major = WINED3D_SM1_VERSION_MAJOR(*byte_code); minor = WINED3D_SM1_VERSION_MINOR(*byte_code); if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) @@ -541,14 +546,11 @@ static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader return NULL; } - priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)); - if (!priv) + if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) return NULL; - if (output_signature) - { + if (output_signature->element_count) FIXME("SM 1-3 shader shouldn't have output signatures.\n"); - } switch (*byte_code >> 16) { @@ -563,10 +565,14 @@ static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader break; default: - FIXME("Unrecognized shader type %#x\n", *byte_code >> 16); + FIXME("Unrecognized shader type %#x.\n", *byte_code >> 16); HeapFree(GetProcessHeap(), 0, priv); return NULL; } + priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(*byte_code); + priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(*byte_code); + + priv->start = &byte_code[1]; return priv; } @@ -579,13 +585,8 @@ static void shader_sm1_free(void *data) static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version) { struct wined3d_sm1_data *priv = data; - DWORD version_token; - version_token = *(*ptr)++; - TRACE("version: 0x%08x\n", version_token); - - priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(version_token); - priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(version_token); + *ptr = priv->start; *shader_version = priv->shader_version; } @@ -648,7 +649,7 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_src_param *src_param, enum wined3d_immconst_type type, enum wined3d_data_type data_type) { - UINT count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1; + unsigned int count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1; src_param->reg.type = WINED3DSPR_IMMCONST; src_param->reg.data_type = data_type; src_param->reg.idx[0].offset = ~0U; @@ -656,7 +657,7 @@ static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_sr src_param->reg.idx[1].offset = ~0U; src_param->reg.idx[1].rel_addr = NULL; src_param->reg.immconst_type = type; - memcpy(src_param->reg.immconst_data, *ptr, count * sizeof(DWORD)); + memcpy(src_param->reg.u.immconst_data, *ptr, count * sizeof(DWORD)); src_param->swizzle = WINED3DSP_NOSWIZZLE; src_param->modifiers = 0; @@ -705,6 +706,19 @@ static void shader_sm1_read_comment(const DWORD **ptr) } } +static void shader_sm1_validate_instruction(struct wined3d_shader_instruction *ins) +{ + if (ins->handler_idx == WINED3DSIH_BREAKP || ins->handler_idx == WINED3DSIH_IF) + { + if (ins->flags) + { + FIXME("Ignoring unexpected instruction flags %#x for %s.\n", + ins->flags, debug_d3dshaderinstructionhandler(ins->handler_idx)); + ins->flags = 0; + } + } +} + static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins) { const struct wined3d_sm1_opcode_info *opcode_info; @@ -732,6 +746,7 @@ static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wi ins->dst = &priv->dst_param; ins->src_count = opcode_info->param_count - opcode_info->dst_count; ins->src = priv->src_param; + memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); p = *ptr; *ptr += shader_skip_opcode(priv, opcode_info, opcode_token); @@ -745,16 +760,16 @@ static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wi shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr); shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_FLOAT); } - else if (ins->handler_idx == WINED3DSIH_DEFI) - { - shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr); - shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_INT); - } else if (ins->handler_idx == WINED3DSIH_DEFB) { shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr); shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_DATA_UINT); } + else if (ins->handler_idx == WINED3DSIH_DEFI) + { + shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr); + shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_INT); + } else { /* Destination token */ @@ -767,10 +782,10 @@ static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wi /* Other source tokens */ for (i = 0; i < ins->src_count; ++i) - { shader_sm1_read_src_param(priv, &p, &priv->src_param[i], &priv->src_rel_addr[i]); - } } + + shader_sm1_validate_instruction(ins); } static BOOL shader_sm1_is_end(void *data, const DWORD **ptr) diff --git a/reactos/dll/directx/wine/wined3d/shader_sm4.c b/reactos/dll/directx/wine/wined3d/shader_sm4.c index fa2b275c4aa..3619685eb03 100644 --- a/reactos/dll/directx/wine/wined3d/shader_sm4.c +++ b/reactos/dll/directx/wine/wined3d/shader_sm4.c @@ -23,6 +23,14 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_INSTRUCTION_MODIFIER (0x1u << 31) +#define WINED3D_SM4_MODIFIER_AOFFIMMI 0x1 +#define WINED3D_SM4_AOFFIMMI_U_SHIFT 9 +#define WINED3D_SM4_AOFFIMMI_U_MASK (0xfu << WINED3D_SM4_AOFFIMMI_U_SHIFT) +#define WINED3D_SM4_AOFFIMMI_V_SHIFT 13 +#define WINED3D_SM4_AOFFIMMI_V_MASK (0xfu << WINED3D_SM4_AOFFIMMI_V_SHIFT) +#define WINED3D_SM4_AOFFIMMI_W_SHIFT 17 +#define WINED3D_SM4_AOFFIMMI_W_MASK (0xfu << WINED3D_SM4_AOFFIMMI_W_SHIFT) + #define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24 #define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0x1fu << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) @@ -33,7 +41,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM4_RESOURCE_TYPE_SHIFT) #define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT 11 -#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7u << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT) +#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x3fu << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT) #define WINED3D_SM4_INDEX_TYPE_SHIFT 11 #define WINED3D_SM4_INDEX_TYPE_MASK (0x1u << WINED3D_SM4_INDEX_TYPE_SHIFT) @@ -50,6 +58,21 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_GLOBAL_FLAGS_SHIFT 11 #define WINED3D_SM4_GLOBAL_FLAGS_MASK (0xffu << WINED3D_SM4_GLOBAL_FLAGS_SHIFT) +#define WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT 11 +#define WINED3D_SM5_CONTROL_POINT_COUNT_MASK (0xffu << WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT) + +#define WINED3D_SM5_FP_ARRAY_SIZE_SHIFT 16 +#define WINED3D_SM5_FP_TABLE_COUNT_MASK 0xffffu + +#define WINED3D_SM5_UAV_FLAGS_SHIFT 15 +#define WINED3D_SM5_UAV_FLAGS_MASK (0x1ffu << WINED3D_SM5_UAV_FLAGS_SHIFT) + +#define WINED3D_SM5_SYNC_FLAGS_SHIFT 11 +#define WINED3D_SM5_SYNC_FLAGS_MASK (0xffu << WINED3D_SM5_SYNC_FLAGS_SHIFT) + +#define WINED3D_SM5_TESSELLATOR_SHIFT 11 +#define WINED3D_SM5_TESSELLATOR_MASK (0xfu << WINED3D_SM5_TESSELLATOR_SHIFT) + #define WINED3D_SM4_OPCODE_MASK 0xff #define WINED3D_SM4_REGISTER_MODIFIER (0x1u << 31) @@ -64,7 +87,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_REGISTER_ORDER_MASK (0x3u << WINED3D_SM4_REGISTER_ORDER_SHIFT) #define WINED3D_SM4_REGISTER_TYPE_SHIFT 12 -#define WINED3D_SM4_REGISTER_TYPE_MASK (0xfu << WINED3D_SM4_REGISTER_TYPE_SHIFT) +#define WINED3D_SM4_REGISTER_TYPE_MASK (0xffu << WINED3D_SM4_REGISTER_TYPE_SHIFT) #define WINED3D_SM4_SWIZZLE_TYPE_SHIFT 2 #define WINED3D_SM4_SWIZZLE_TYPE_MASK (0x3u << WINED3D_SM4_SWIZZLE_TYPE_SHIFT) @@ -86,107 +109,226 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode); #define WINED3D_SM4_INSTRUCTION_FLAG_SATURATE 0x4 +#define WINED3D_SM4_CONDITIONAL_NZ (0x1u << 18) + enum wined3d_sm4_opcode { - WINED3D_SM4_OP_ADD = 0x00, - WINED3D_SM4_OP_AND = 0x01, - WINED3D_SM4_OP_BREAK = 0x02, - WINED3D_SM4_OP_BREAKC = 0x03, - WINED3D_SM4_OP_CUT = 0x09, - WINED3D_SM4_OP_DERIV_RTX = 0x0b, - WINED3D_SM4_OP_DERIV_RTY = 0x0c, - WINED3D_SM4_OP_DISCARD = 0x0d, - WINED3D_SM4_OP_DIV = 0x0e, - WINED3D_SM4_OP_DP2 = 0x0f, - WINED3D_SM4_OP_DP3 = 0x10, - WINED3D_SM4_OP_DP4 = 0x11, - WINED3D_SM4_OP_ELSE = 0x12, - WINED3D_SM4_OP_EMIT = 0x13, - WINED3D_SM4_OP_ENDIF = 0x15, - WINED3D_SM4_OP_ENDLOOP = 0x16, - WINED3D_SM4_OP_EQ = 0x18, - WINED3D_SM4_OP_EXP = 0x19, - WINED3D_SM4_OP_FRC = 0x1a, - WINED3D_SM4_OP_FTOI = 0x1b, - WINED3D_SM4_OP_FTOU = 0x1c, - WINED3D_SM4_OP_GE = 0x1d, - WINED3D_SM4_OP_IADD = 0x1e, - WINED3D_SM4_OP_IF = 0x1f, - WINED3D_SM4_OP_IEQ = 0x20, - WINED3D_SM4_OP_IGE = 0x21, - WINED3D_SM4_OP_ILT = 0x22, - WINED3D_SM4_OP_IMAD = 0x23, - WINED3D_SM4_OP_IMAX = 0x24, - WINED3D_SM4_OP_IMIN = 0x25, - WINED3D_SM4_OP_IMUL = 0x26, - WINED3D_SM4_OP_INE = 0x27, - WINED3D_SM4_OP_INEG = 0x28, - WINED3D_SM4_OP_ISHL = 0x29, - WINED3D_SM4_OP_ITOF = 0x2b, - WINED3D_SM4_OP_LD = 0x2d, - WINED3D_SM4_OP_LOG = 0x2f, - WINED3D_SM4_OP_LOOP = 0x30, - WINED3D_SM4_OP_LT = 0x31, - WINED3D_SM4_OP_MAD = 0x32, - WINED3D_SM4_OP_MIN = 0x33, - WINED3D_SM4_OP_MAX = 0x34, - WINED3D_SM4_OP_SHADER_DATA = 0x35, - WINED3D_SM4_OP_MOV = 0x36, - WINED3D_SM4_OP_MOVC = 0x37, - WINED3D_SM4_OP_MUL = 0x38, - WINED3D_SM4_OP_NE = 0x39, - WINED3D_SM4_OP_NOT = 0x3b, - WINED3D_SM4_OP_OR = 0x3c, - WINED3D_SM4_OP_RESINFO = 0x3d, - WINED3D_SM4_OP_RET = 0x3e, - WINED3D_SM4_OP_ROUND_NI = 0x41, - WINED3D_SM4_OP_ROUND_PI = 0x42, - WINED3D_SM4_OP_ROUND_Z = 0x43, - WINED3D_SM4_OP_RSQ = 0x44, - WINED3D_SM4_OP_SAMPLE = 0x45, - WINED3D_SM4_OP_SAMPLE_C = 0x46, - WINED3D_SM4_OP_SAMPLE_C_LZ = 0x47, - WINED3D_SM4_OP_SAMPLE_LOD = 0x48, - WINED3D_SM4_OP_SAMPLE_GRAD = 0x49, - WINED3D_SM4_OP_SAMPLE_B = 0x4a, - WINED3D_SM4_OP_SQRT = 0x4b, - WINED3D_SM4_OP_SINCOS = 0x4d, - WINED3D_SM4_OP_UDIV = 0x4e, - WINED3D_SM4_OP_UGE = 0x50, - WINED3D_SM4_OP_USHR = 0x55, - WINED3D_SM4_OP_UTOF = 0x56, - WINED3D_SM4_OP_XOR = 0x57, - WINED3D_SM4_OP_DCL_RESOURCE = 0x58, - WINED3D_SM4_OP_DCL_CONSTANT_BUFFER = 0x59, - WINED3D_SM4_OP_DCL_SAMPLER = 0x5a, - WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY = 0x5c, - WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE = 0x5d, - WINED3D_SM4_OP_DCL_VERTICES_OUT = 0x5e, - WINED3D_SM4_OP_DCL_INPUT = 0x5f, - WINED3D_SM4_OP_DCL_INPUT_SGV = 0x60, - WINED3D_SM4_OP_DCL_INPUT_SIV = 0x61, - WINED3D_SM4_OP_DCL_INPUT_PS = 0x62, - WINED3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, - WINED3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, - WINED3D_SM4_OP_DCL_OUTPUT = 0x65, - WINED3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, - WINED3D_SM4_OP_DCL_TEMPS = 0x68, - WINED3D_SM4_OP_DCL_GLOBAL_FLAGS = 0x6a, + WINED3D_SM4_OP_ADD = 0x00, + WINED3D_SM4_OP_AND = 0x01, + WINED3D_SM4_OP_BREAK = 0x02, + WINED3D_SM4_OP_BREAKC = 0x03, + WINED3D_SM4_OP_CASE = 0x06, + WINED3D_SM4_OP_CONTINUE = 0x07, + WINED3D_SM4_OP_CONTINUEC = 0x08, + WINED3D_SM4_OP_CUT = 0x09, + WINED3D_SM4_OP_DEFAULT = 0x0a, + WINED3D_SM4_OP_DERIV_RTX = 0x0b, + WINED3D_SM4_OP_DERIV_RTY = 0x0c, + WINED3D_SM4_OP_DISCARD = 0x0d, + WINED3D_SM4_OP_DIV = 0x0e, + WINED3D_SM4_OP_DP2 = 0x0f, + WINED3D_SM4_OP_DP3 = 0x10, + WINED3D_SM4_OP_DP4 = 0x11, + WINED3D_SM4_OP_ELSE = 0x12, + WINED3D_SM4_OP_EMIT = 0x13, + WINED3D_SM4_OP_ENDIF = 0x15, + WINED3D_SM4_OP_ENDLOOP = 0x16, + WINED3D_SM4_OP_ENDSWITCH = 0x17, + WINED3D_SM4_OP_EQ = 0x18, + WINED3D_SM4_OP_EXP = 0x19, + WINED3D_SM4_OP_FRC = 0x1a, + WINED3D_SM4_OP_FTOI = 0x1b, + WINED3D_SM4_OP_FTOU = 0x1c, + WINED3D_SM4_OP_GE = 0x1d, + WINED3D_SM4_OP_IADD = 0x1e, + WINED3D_SM4_OP_IF = 0x1f, + WINED3D_SM4_OP_IEQ = 0x20, + WINED3D_SM4_OP_IGE = 0x21, + WINED3D_SM4_OP_ILT = 0x22, + WINED3D_SM4_OP_IMAD = 0x23, + WINED3D_SM4_OP_IMAX = 0x24, + WINED3D_SM4_OP_IMIN = 0x25, + WINED3D_SM4_OP_IMUL = 0x26, + WINED3D_SM4_OP_INE = 0x27, + WINED3D_SM4_OP_INEG = 0x28, + WINED3D_SM4_OP_ISHL = 0x29, + WINED3D_SM4_OP_ISHR = 0x2a, + WINED3D_SM4_OP_ITOF = 0x2b, + WINED3D_SM4_OP_LABEL = 0x2c, + WINED3D_SM4_OP_LD = 0x2d, + WINED3D_SM4_OP_LD2DMS = 0x2e, + WINED3D_SM4_OP_LOG = 0x2f, + WINED3D_SM4_OP_LOOP = 0x30, + WINED3D_SM4_OP_LT = 0x31, + WINED3D_SM4_OP_MAD = 0x32, + WINED3D_SM4_OP_MIN = 0x33, + WINED3D_SM4_OP_MAX = 0x34, + WINED3D_SM4_OP_SHADER_DATA = 0x35, + WINED3D_SM4_OP_MOV = 0x36, + WINED3D_SM4_OP_MOVC = 0x37, + WINED3D_SM4_OP_MUL = 0x38, + WINED3D_SM4_OP_NE = 0x39, + WINED3D_SM4_OP_NOT = 0x3b, + WINED3D_SM4_OP_OR = 0x3c, + WINED3D_SM4_OP_RESINFO = 0x3d, + WINED3D_SM4_OP_RET = 0x3e, + WINED3D_SM4_OP_RETC = 0x3f, + WINED3D_SM4_OP_ROUND_NE = 0x40, + WINED3D_SM4_OP_ROUND_NI = 0x41, + WINED3D_SM4_OP_ROUND_PI = 0x42, + WINED3D_SM4_OP_ROUND_Z = 0x43, + WINED3D_SM4_OP_RSQ = 0x44, + WINED3D_SM4_OP_SAMPLE = 0x45, + WINED3D_SM4_OP_SAMPLE_C = 0x46, + WINED3D_SM4_OP_SAMPLE_C_LZ = 0x47, + WINED3D_SM4_OP_SAMPLE_LOD = 0x48, + WINED3D_SM4_OP_SAMPLE_GRAD = 0x49, + WINED3D_SM4_OP_SAMPLE_B = 0x4a, + WINED3D_SM4_OP_SQRT = 0x4b, + WINED3D_SM4_OP_SWITCH = 0x4c, + WINED3D_SM4_OP_SINCOS = 0x4d, + WINED3D_SM4_OP_UDIV = 0x4e, + WINED3D_SM4_OP_ULT = 0x4f, + WINED3D_SM4_OP_UGE = 0x50, + WINED3D_SM4_OP_UMUL = 0x51, + WINED3D_SM4_OP_UMAX = 0x53, + WINED3D_SM4_OP_UMIN = 0x54, + WINED3D_SM4_OP_USHR = 0x55, + WINED3D_SM4_OP_UTOF = 0x56, + WINED3D_SM4_OP_XOR = 0x57, + WINED3D_SM4_OP_DCL_RESOURCE = 0x58, + WINED3D_SM4_OP_DCL_CONSTANT_BUFFER = 0x59, + WINED3D_SM4_OP_DCL_SAMPLER = 0x5a, + WINED3D_SM4_OP_DCL_INDEX_RANGE = 0x5b, + WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY = 0x5c, + WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE = 0x5d, + WINED3D_SM4_OP_DCL_VERTICES_OUT = 0x5e, + WINED3D_SM4_OP_DCL_INPUT = 0x5f, + WINED3D_SM4_OP_DCL_INPUT_SGV = 0x60, + WINED3D_SM4_OP_DCL_INPUT_SIV = 0x61, + WINED3D_SM4_OP_DCL_INPUT_PS = 0x62, + WINED3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, + WINED3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, + WINED3D_SM4_OP_DCL_OUTPUT = 0x65, + WINED3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, + WINED3D_SM4_OP_DCL_TEMPS = 0x68, + WINED3D_SM4_OP_DCL_INDEXABLE_TEMP = 0x69, + WINED3D_SM4_OP_DCL_GLOBAL_FLAGS = 0x6a, + WINED3D_SM4_OP_LOD = 0x6c, + WINED3D_SM4_OP_GATHER4 = 0x6d, + WINED3D_SM4_OP_SAMPLE_POS = 0x6e, + WINED3D_SM4_OP_SAMPLE_INFO = 0x6f, + WINED3D_SM5_OP_HS_DECLS = 0x71, + WINED3D_SM5_OP_HS_CONTROL_POINT_PHASE = 0x72, + WINED3D_SM5_OP_HS_FORK_PHASE = 0x73, + WINED3D_SM5_OP_HS_JOIN_PHASE = 0x74, + WINED3D_SM5_OP_EMIT_STREAM = 0x75, + WINED3D_SM5_OP_CUT_STREAM = 0x76, + WINED3D_SM5_OP_FCALL = 0x78, + WINED3D_SM5_OP_BUFINFO = 0x79, + WINED3D_SM5_OP_DERIV_RTX_COARSE = 0x7a, + WINED3D_SM5_OP_DERIV_RTX_FINE = 0x7b, + WINED3D_SM5_OP_DERIV_RTY_COARSE = 0x7c, + WINED3D_SM5_OP_DERIV_RTY_FINE = 0x7d, + WINED3D_SM5_OP_GATHER4_C = 0x7e, + WINED3D_SM5_OP_GATHER4_PO = 0x7f, + WINED3D_SM5_OP_GATHER4_PO_C = 0x80, + WINED3D_SM5_OP_RCP = 0x81, + WINED3D_SM5_OP_F32TOF16 = 0x82, + WINED3D_SM5_OP_F16TOF32 = 0x83, + WINED3D_SM5_OP_COUNTBITS = 0x86, + WINED3D_SM5_OP_FIRSTBIT_HI = 0x87, + WINED3D_SM5_OP_FIRSTBIT_LO = 0x88, + WINED3D_SM5_OP_FIRSTBIT_SHI = 0x89, + WINED3D_SM5_OP_UBFE = 0x8a, + WINED3D_SM5_OP_IBFE = 0x8b, + WINED3D_SM5_OP_BFI = 0x8c, + WINED3D_SM5_OP_BFREV = 0x8d, + WINED3D_SM5_OP_SWAPC = 0x8e, + WINED3D_SM5_OP_DCL_STREAM = 0x8f, + WINED3D_SM5_OP_DCL_FUNCTION_BODY = 0x90, + WINED3D_SM5_OP_DCL_FUNCTION_TABLE = 0x91, + WINED3D_SM5_OP_DCL_INTERFACE = 0x92, + WINED3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT = 0x93, + WINED3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT = 0x94, + WINED3D_SM5_OP_DCL_TESSELLATOR_DOMAIN = 0x95, + WINED3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING = 0x96, + WINED3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE = 0x97, + WINED3D_SM5_OP_DCL_HS_MAX_TESSFACTOR = 0x98, + WINED3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT = 0x99, + WINED3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT = 0x9a, + WINED3D_SM5_OP_DCL_THREAD_GROUP = 0x9b, + WINED3D_SM5_OP_DCL_UAV_TYPED = 0x9c, + WINED3D_SM5_OP_DCL_UAV_RAW = 0x9d, + WINED3D_SM5_OP_DCL_UAV_STRUCTURED = 0x9e, + WINED3D_SM5_OP_DCL_TGSM_RAW = 0x9f, + WINED3D_SM5_OP_DCL_TGSM_STRUCTURED = 0xa0, + WINED3D_SM5_OP_DCL_RESOURCE_RAW = 0xa1, + WINED3D_SM5_OP_DCL_RESOURCE_STRUCTURED = 0xa2, + WINED3D_SM5_OP_LD_UAV_TYPED = 0xa3, + WINED3D_SM5_OP_STORE_UAV_TYPED = 0xa4, + WINED3D_SM5_OP_LD_RAW = 0xa5, + WINED3D_SM5_OP_STORE_RAW = 0xa6, + WINED3D_SM5_OP_LD_STRUCTURED = 0xa7, + WINED3D_SM5_OP_STORE_STRUCTURED = 0xa8, + WINED3D_SM5_OP_ATOMIC_AND = 0xa9, + WINED3D_SM5_OP_ATOMIC_OR = 0xaa, + WINED3D_SM5_OP_ATOMIC_XOR = 0xab, + WINED3D_SM5_OP_ATOMIC_CMP_STORE = 0xac, + WINED3D_SM5_OP_ATOMIC_IADD = 0xad, + WINED3D_SM5_OP_ATOMIC_IMAX = 0xae, + WINED3D_SM5_OP_ATOMIC_IMIN = 0xaf, + WINED3D_SM5_OP_ATOMIC_UMAX = 0xb0, + WINED3D_SM5_OP_ATOMIC_UMIN = 0xb1, + WINED3D_SM5_OP_IMM_ATOMIC_ALLOC = 0xb2, + WINED3D_SM5_OP_IMM_ATOMIC_CONSUME = 0xb3, + WINED3D_SM5_OP_IMM_ATOMIC_IADD = 0xb4, + WINED3D_SM5_OP_IMM_ATOMIC_AND = 0xb5, + WINED3D_SM5_OP_IMM_ATOMIC_OR = 0xb6, + WINED3D_SM5_OP_IMM_ATOMIC_XOR = 0xb7, + WINED3D_SM5_OP_IMM_ATOMIC_EXCH = 0xb8, + WINED3D_SM5_OP_IMM_ATOMIC_CMP_EXCH = 0xb9, + WINED3D_SM5_OP_IMM_ATOMIC_IMAX = 0xba, + WINED3D_SM5_OP_IMM_ATOMIC_IMIN = 0xbb, + WINED3D_SM5_OP_IMM_ATOMIC_UMAX = 0xbc, + WINED3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, + WINED3D_SM5_OP_SYNC = 0xbe, + WINED3D_SM5_OP_DCL_GS_INSTANCES = 0xce, }; enum wined3d_sm4_register_type { - WINED3D_SM4_RT_TEMP = 0x0, - WINED3D_SM4_RT_INPUT = 0x1, - WINED3D_SM4_RT_OUTPUT = 0x2, - WINED3D_SM4_RT_IMMCONST = 0x4, - WINED3D_SM4_RT_SAMPLER = 0x6, - WINED3D_SM4_RT_RESOURCE = 0x7, - WINED3D_SM4_RT_CONSTBUFFER = 0x8, - WINED3D_SM4_RT_IMMCONSTBUFFER = 0x9, - WINED3D_SM4_RT_PRIMID = 0xb, - WINED3D_SM4_RT_DEPTHOUT = 0xc, - WINED3D_SM4_RT_NULL = 0xd, + WINED3D_SM4_RT_TEMP = 0x00, + WINED3D_SM4_RT_INPUT = 0x01, + WINED3D_SM4_RT_OUTPUT = 0x02, + WINED3D_SM4_RT_INDEXABLE_TEMP = 0x03, + WINED3D_SM4_RT_IMMCONST = 0x04, + WINED3D_SM4_RT_SAMPLER = 0x06, + WINED3D_SM4_RT_RESOURCE = 0x07, + WINED3D_SM4_RT_CONSTBUFFER = 0x08, + WINED3D_SM4_RT_IMMCONSTBUFFER = 0x09, + WINED3D_SM4_RT_PRIMID = 0x0b, + WINED3D_SM4_RT_DEPTHOUT = 0x0c, + WINED3D_SM4_RT_NULL = 0x0d, + WINED3D_SM4_RT_OMASK = 0x0f, + WINED3D_SM5_RT_STREAM = 0x10, + WINED3D_SM5_RT_FUNCTION_BODY = 0x11, + WINED3D_SM5_RT_FUNCTION_POINTER = 0x13, + WINED3D_SM5_RT_OUTPUT_CONTROL_POINT_ID = 0x16, + WINED3D_SM5_RT_FORK_INSTANCE_ID = 0x17, + WINED3D_SM5_RT_JOIN_INSTANCE_ID = 0x18, + WINED3D_SM5_RT_INPUT_CONTROL_POINT = 0x19, + WINED3D_SM5_RT_OUTPUT_CONTROL_POINT = 0x1a, + WINED3D_SM5_RT_PATCH_CONSTANT_DATA = 0x1b, + WINED3D_SM5_RT_DOMAIN_LOCATION = 0x1c, + WINED3D_SM5_RT_UAV = 0x1e, + WINED3D_SM5_RT_SHARED_MEMORY = 0x1f, + WINED3D_SM5_RT_THREAD_ID = 0x20, + WINED3D_SM5_RT_THREAD_GROUP_ID = 0x21, + WINED3D_SM5_RT_LOCAL_THREAD_ID = 0x22, + WINED3D_SM5_RT_COVERAGE = 0x23, + WINED3D_SM5_RT_LOCAL_THREAD_INDEX = 0x24, + WINED3D_SM5_RT_GS_INSTANCE_ID = 0x25, }; enum wined3d_sm4_output_primitive_type @@ -198,11 +340,43 @@ enum wined3d_sm4_output_primitive_type enum wined3d_sm4_input_primitive_type { - WINED3D_SM4_INPUT_PT_POINT = 0x1, - WINED3D_SM4_INPUT_PT_LINE = 0x2, - WINED3D_SM4_INPUT_PT_TRIANGLE = 0x3, - WINED3D_SM4_INPUT_PT_LINEADJ = 0x6, - WINED3D_SM4_INPUT_PT_TRIANGLEADJ = 0x7, + WINED3D_SM4_INPUT_PT_POINT = 0x01, + WINED3D_SM4_INPUT_PT_LINE = 0x02, + WINED3D_SM4_INPUT_PT_TRIANGLE = 0x03, + WINED3D_SM4_INPUT_PT_LINEADJ = 0x06, + WINED3D_SM4_INPUT_PT_TRIANGLEADJ = 0x07, + WINED3D_SM5_INPUT_PT_PATCH1 = 0x08, + WINED3D_SM5_INPUT_PT_PATCH2 = 0x09, + WINED3D_SM5_INPUT_PT_PATCH3 = 0x0a, + WINED3D_SM5_INPUT_PT_PATCH4 = 0x0b, + WINED3D_SM5_INPUT_PT_PATCH5 = 0x0c, + WINED3D_SM5_INPUT_PT_PATCH6 = 0x0d, + WINED3D_SM5_INPUT_PT_PATCH7 = 0x0e, + WINED3D_SM5_INPUT_PT_PATCH8 = 0x0f, + WINED3D_SM5_INPUT_PT_PATCH9 = 0x10, + WINED3D_SM5_INPUT_PT_PATCH10 = 0x11, + WINED3D_SM5_INPUT_PT_PATCH11 = 0x12, + WINED3D_SM5_INPUT_PT_PATCH12 = 0x13, + WINED3D_SM5_INPUT_PT_PATCH13 = 0x14, + WINED3D_SM5_INPUT_PT_PATCH14 = 0x15, + WINED3D_SM5_INPUT_PT_PATCH15 = 0x16, + WINED3D_SM5_INPUT_PT_PATCH16 = 0x17, + WINED3D_SM5_INPUT_PT_PATCH17 = 0x18, + WINED3D_SM5_INPUT_PT_PATCH18 = 0x19, + WINED3D_SM5_INPUT_PT_PATCH19 = 0x1a, + WINED3D_SM5_INPUT_PT_PATCH20 = 0x1b, + WINED3D_SM5_INPUT_PT_PATCH21 = 0x1c, + WINED3D_SM5_INPUT_PT_PATCH22 = 0x1d, + WINED3D_SM5_INPUT_PT_PATCH23 = 0x1e, + WINED3D_SM5_INPUT_PT_PATCH24 = 0x1f, + WINED3D_SM5_INPUT_PT_PATCH25 = 0x20, + WINED3D_SM5_INPUT_PT_PATCH26 = 0x21, + WINED3D_SM5_INPUT_PT_PATCH27 = 0x22, + WINED3D_SM5_INPUT_PT_PATCH28 = 0x23, + WINED3D_SM5_INPUT_PT_PATCH29 = 0x24, + WINED3D_SM5_INPUT_PT_PATCH30 = 0x25, + WINED3D_SM5_INPUT_PT_PATCH31 = 0x26, + WINED3D_SM5_INPUT_PT_PATCH32 = 0x27, }; enum wined3d_sm4_swizzle_type @@ -229,6 +403,7 @@ enum wined3d_sm4_resource_type WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY = 0x7, WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY = 0x8, WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY = 0x9, + WINED3D_SM4_RESOURCE_TEXTURE_CUBEARRAY = 0xa, }; enum wined3d_sm4_data_type @@ -261,13 +436,9 @@ struct wined3d_shader_src_param_entry struct wined3d_sm4_data { struct wined3d_shader_version shader_version; - const DWORD *end; + const DWORD *start, *end; - struct - { - enum wined3d_shader_register_type register_type; - UINT register_idx; - } output_map[MAX_REG_OUTPUT]; + unsigned int output_map[MAX_REG_OUTPUT]; struct wined3d_shader_src_param src_param[5]; struct wined3d_shader_dst_param dst_param[2]; @@ -282,126 +453,9 @@ struct wined3d_sm4_opcode_info enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; const char *dst_info; const char *src_info; -}; - -struct sysval_map -{ - enum wined3d_sysval_semantic sysval; - enum wined3d_shader_register_type register_type; - UINT register_idx; -}; - -/* - * F -> WINED3D_DATA_FLOAT - * I -> WINED3D_DATA_INT - * R -> WINED3D_DATA_RESOURCE - * S -> WINED3D_DATA_SAMPLER - * U -> WINED3D_DATA_UINT - */ -static const struct wined3d_sm4_opcode_info opcode_table[] = -{ - {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "F", "FF"}, - {WINED3D_SM4_OP_AND, WINED3DSIH_AND, "U", "UU"}, - {WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, "", ""}, - {WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, "", "U"}, - {WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, "", ""}, - {WINED3D_SM4_OP_DERIV_RTX, WINED3DSIH_DSX, "F", "F"}, - {WINED3D_SM4_OP_DERIV_RTY, WINED3DSIH_DSY, "F", "F"}, - {WINED3D_SM4_OP_DISCARD, WINED3DSIH_TEXKILL, "", "U"}, - {WINED3D_SM4_OP_DIV, WINED3DSIH_DIV, "F", "FF"}, - {WINED3D_SM4_OP_DP2, WINED3DSIH_DP2, "F", "FF"}, - {WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, "F", "FF"}, - {WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, "F", "FF"}, - {WINED3D_SM4_OP_ELSE, WINED3DSIH_ELSE, "", ""}, - {WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, "", ""}, - {WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, "", ""}, - {WINED3D_SM4_OP_ENDLOOP, WINED3DSIH_ENDLOOP, "", ""}, - {WINED3D_SM4_OP_EQ, WINED3DSIH_EQ, "U", "FF"}, - {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, "F", "F"}, - {WINED3D_SM4_OP_FRC, WINED3DSIH_FRC, "F", "F"}, - {WINED3D_SM4_OP_FTOI, WINED3DSIH_FTOI, "I", "F"}, - {WINED3D_SM4_OP_FTOU, WINED3DSIH_FTOU, "U", "F"}, - {WINED3D_SM4_OP_GE, WINED3DSIH_GE, "U", "FF"}, - {WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, "I", "II"}, - {WINED3D_SM4_OP_IF, WINED3DSIH_IF, "", "U"}, - {WINED3D_SM4_OP_IEQ, WINED3DSIH_IEQ, "U", "II"}, - {WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, "U", "II"}, - {WINED3D_SM4_OP_ILT, WINED3DSIH_ILT, "U", "II"}, - {WINED3D_SM4_OP_IMAD, WINED3DSIH_IMAD, "I", "III"}, - {WINED3D_SM4_OP_IMAX, WINED3DSIH_IMAX, "I", "II"}, - {WINED3D_SM4_OP_IMIN, WINED3DSIH_IMIN, "I", "II"}, - {WINED3D_SM4_OP_IMUL, WINED3DSIH_IMUL, "II", "II"}, - {WINED3D_SM4_OP_INE, WINED3DSIH_INE, "U", "II"}, - {WINED3D_SM4_OP_INEG, WINED3DSIH_INEG, "I", "I"}, - {WINED3D_SM4_OP_ISHL, WINED3DSIH_ISHL, "I", "II"}, - {WINED3D_SM4_OP_ITOF, WINED3DSIH_ITOF, "F", "I"}, - {WINED3D_SM4_OP_LD, WINED3DSIH_LD, "U", "IR"}, - {WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, "F", "F"}, - {WINED3D_SM4_OP_LOOP, WINED3DSIH_LOOP, "", ""}, - {WINED3D_SM4_OP_LT, WINED3DSIH_LT, "U", "FF"}, - {WINED3D_SM4_OP_MAD, WINED3DSIH_MAD, "F", "FFF"}, - {WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, "F", "FF"}, - {WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, "F", "FF"}, - {WINED3D_SM4_OP_SHADER_DATA, WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", ""}, - {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "F", "F"}, - {WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "F", "UFF"}, - {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "F", "FF"}, - {WINED3D_SM4_OP_NE, WINED3DSIH_NE, "U", "FF"}, - {WINED3D_SM4_OP_NOT, WINED3DSIH_NOT, "U", "U"}, - {WINED3D_SM4_OP_OR, WINED3DSIH_OR, "U", "UU"}, - {WINED3D_SM4_OP_RESINFO, WINED3DSIH_RESINFO, "F", "IR"}, - {WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""}, - {WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "F", "F"}, - {WINED3D_SM4_OP_ROUND_PI, WINED3DSIH_ROUND_PI, "F", "F"}, - {WINED3D_SM4_OP_ROUND_Z, WINED3DSIH_ROUND_Z, "F", "F"}, - {WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "F", "F"}, - {WINED3D_SM4_OP_SAMPLE, WINED3DSIH_SAMPLE, "U", "FRS"}, - {WINED3D_SM4_OP_SAMPLE_C, WINED3DSIH_SAMPLE_C, "F", "FRSF"}, - {WINED3D_SM4_OP_SAMPLE_C_LZ, WINED3DSIH_SAMPLE_C_LZ, "F", "FRSF"}, - {WINED3D_SM4_OP_SAMPLE_LOD, WINED3DSIH_SAMPLE_LOD, "U", "FRSF"}, - {WINED3D_SM4_OP_SAMPLE_GRAD, WINED3DSIH_SAMPLE_GRAD, "U", "FRSFF"}, - {WINED3D_SM4_OP_SAMPLE_B, WINED3DSIH_SAMPLE_B, "U", "FRSF"}, - {WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "F", "F"}, - {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "FF", "F"}, - {WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "UU", "UU"}, - {WINED3D_SM4_OP_UGE, WINED3DSIH_UGE, "U", "UU"}, - {WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "U", "UU"}, - {WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "F", "U"}, - {WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "U", "UU"}, - {WINED3D_SM4_OP_DCL_RESOURCE, WINED3DSIH_DCL, "R", ""}, - {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", ""}, - {WINED3D_SM4_OP_DCL_SAMPLER, WINED3DSIH_DCL_SAMPLER, "", ""}, - {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", ""}, - {WINED3D_SM4_OP_DCL_VERTICES_OUT, WINED3DSIH_DCL_VERTICES_OUT, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT, WINED3DSIH_DCL_INPUT, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_SGV, WINED3DSIH_DCL_INPUT_SGV, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_SIV, WINED3DSIH_DCL_INPUT_SIV, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_PS, WINED3DSIH_DCL_INPUT_PS, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_PS_SGV, WINED3DSIH_DCL_INPUT_PS_SGV, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_PS_SIV, WINED3DSIH_DCL_INPUT_PS_SIV, "", ""}, - {WINED3D_SM4_OP_DCL_OUTPUT, WINED3DSIH_DCL_OUTPUT, "", ""}, - {WINED3D_SM4_OP_DCL_OUTPUT_SIV, WINED3DSIH_DCL_OUTPUT_SIV, "", ""}, - {WINED3D_SM4_OP_DCL_TEMPS, WINED3DSIH_DCL_TEMPS, "", ""}, - {WINED3D_SM4_OP_DCL_GLOBAL_FLAGS, WINED3DSIH_DCL_GLOBAL_FLAGS, "", ""}, -}; - -static const enum wined3d_shader_register_type register_type_table[] = -{ - /* WINED3D_SM4_RT_TEMP */ WINED3DSPR_TEMP, - /* WINED3D_SM4_RT_INPUT */ WINED3DSPR_INPUT, - /* WINED3D_SM4_RT_OUTPUT */ WINED3DSPR_OUTPUT, - /* UNKNOWN */ 0, - /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST, - /* UNKNOWN */ 0, - /* WINED3D_SM4_RT_SAMPLER */ WINED3DSPR_SAMPLER, - /* WINED3D_SM4_RT_RESOURCE */ WINED3DSPR_RESOURCE, - /* WINED3D_SM4_RT_CONSTBUFFER */ WINED3DSPR_CONSTBUFFER, - /* WINED3D_SM4_RT_IMMCONSTBUFFER */ WINED3DSPR_IMMCONSTBUFFER, - /* UNKNOWN */ 0, - /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID, - /* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT, - /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL, + void (*read_opcode_func)(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv); }; static const enum wined3d_primitive_type output_primitive_type_table[] = @@ -426,19 +480,6 @@ static const enum wined3d_primitive_type input_primitive_type_table[] = /* WINED3D_SM4_INPUT_PT_TRIANGLEADJ */ WINED3D_PT_TRIANGLELIST_ADJ, }; -static const struct sysval_map sysval_map[] = -{ - {WINED3D_SV_DEPTH, WINED3DSPR_DEPTHOUT, 0}, - {WINED3D_SV_TARGET0, WINED3DSPR_COLOROUT, 0}, - {WINED3D_SV_TARGET1, WINED3DSPR_COLOROUT, 1}, - {WINED3D_SV_TARGET2, WINED3DSPR_COLOROUT, 2}, - {WINED3D_SV_TARGET3, WINED3DSPR_COLOROUT, 3}, - {WINED3D_SV_TARGET4, WINED3DSPR_COLOROUT, 4}, - {WINED3D_SV_TARGET5, WINED3DSPR_COLOROUT, 5}, - {WINED3D_SV_TARGET6, WINED3DSPR_COLOROUT, 6}, - {WINED3D_SV_TARGET7, WINED3DSPR_COLOROUT, 7}, -}; - static const enum wined3d_shader_resource_type resource_type_table[] = { /* 0 */ WINED3D_SHADER_RESOURCE_NONE, @@ -451,6 +492,7 @@ static const enum wined3d_shader_resource_type resource_type_table[] = /* WINED3D_SM4_RESOURCE_TEXTURE_1DARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY, /* WINED3D_SM4_RESOURCE_TEXTURE_2DARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY, /* WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY, + /* WINED3D_SM4_RESOURCE_TEXTURE_CUBEARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY, }; static const enum wined3d_data_type data_type_table[] = @@ -465,6 +507,637 @@ static const enum wined3d_data_type data_type_table[] = static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param); +static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, + enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param); + +static void shader_sm4_read_conditional_op(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_UINT, &priv->src_param[0]); + ins->flags = (opcode_token & WINED3D_SM4_CONDITIONAL_NZ) ? + WINED3D_SHADER_CONDITIONAL_OP_NZ : WINED3D_SHADER_CONDITIONAL_OP_Z; +} + +static void shader_sm4_read_shader_data(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + enum wined3d_sm4_shader_data_type type; + unsigned int icb_size; + + type = (opcode_token & WINED3D_SM4_SHADER_DATA_TYPE_MASK) >> WINED3D_SM4_SHADER_DATA_TYPE_SHIFT; + if (type != WINED3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) + { + FIXME("Ignoring shader data type %#x.\n", type); + ins->handler_idx = WINED3DSIH_NOP; + return; + } + + ++tokens; + icb_size = token_count - 1; + if (icb_size % 4 || icb_size > MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE) + { + FIXME("Unexpected immediate constant buffer size %u.\n", icb_size); + ins->handler_idx = WINED3DSIH_TABLE_SIZE; + return; + } + + priv->icb.vec4_count = icb_size / 4; + memcpy(priv->icb.data, tokens, sizeof(*tokens) * icb_size); + ins->declaration.icb = &priv->icb; +} + +static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + enum wined3d_sm4_resource_type resource_type; + enum wined3d_sm4_data_type data_type; + enum wined3d_data_type reg_data_type; + DWORD components; + + resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT; + if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table))) + { + FIXME("Unhandled resource type %#x.\n", resource_type); + ins->declaration.semantic.resource_type = WINED3D_SHADER_RESOURCE_NONE; + } + else + { + ins->declaration.semantic.resource_type = resource_type_table[resource_type]; + } + reg_data_type = opcode == WINED3D_SM4_OP_DCL_RESOURCE ? WINED3D_DATA_RESOURCE : WINED3D_DATA_UAV; + shader_sm4_read_dst_param(priv, &tokens, reg_data_type, &ins->declaration.semantic.reg); + + components = *tokens++; + if ((components & 0xfff0) != (components & 0xf) * 0x1110) + FIXME("Components (%#x) have different data types.\n", components); + data_type = components & 0xf; + + if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) + { + FIXME("Unhandled data type %#x.\n", data_type); + ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT; + } + else + { + ins->declaration.semantic.resource_data_type = data_type_table[data_type]; + } + + if (reg_data_type == WINED3D_DATA_UAV) + ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT; +} + +static void shader_sm4_read_dcl_constant_buffer(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.src); + if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK) + ins->flags |= WINED3DSI_INDEXED_DYNAMIC; +} + +static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT; + if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON) + FIXME("Unhandled sampler mode %#x.\n", ins->flags); + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_SAMPLER, &ins->declaration.dst); +} + +static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_OPAQUE, &ins->declaration.index_range.first_register); + ins->declaration.index_range.last_register = *tokens; +} + +static void shader_sm4_read_dcl_output_topology(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + enum wined3d_sm4_output_primitive_type primitive_type; + + primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT; + if (primitive_type >= ARRAY_SIZE(output_primitive_type_table)) + ins->declaration.primitive_type.type = WINED3D_PT_UNDEFINED; + else + ins->declaration.primitive_type.type = output_primitive_type_table[primitive_type]; + + if (ins->declaration.primitive_type.type == WINED3D_PT_UNDEFINED) + FIXME("Unhandled output primitive type %#x.\n", primitive_type); +} + +static void shader_sm4_read_dcl_input_primitive(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + enum wined3d_sm4_input_primitive_type primitive_type; + + primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT; + if (WINED3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= WINED3D_SM5_INPUT_PT_PATCH32) + { + ins->declaration.primitive_type.type = WINED3D_PT_PATCH; + ins->declaration.primitive_type.patch_vertex_count = primitive_type - WINED3D_SM5_INPUT_PT_PATCH1 + 1; + } + else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table)) + { + ins->declaration.primitive_type.type = WINED3D_PT_UNDEFINED; + } + else + { + ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type]; + } + + if (ins->declaration.primitive_type.type == WINED3D_PT_UNDEFINED) + FIXME("Unhandled input primitive type %#x.\n", primitive_type); +} + +static void shader_sm4_read_declaration_count(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.count = *tokens; +} + +static void shader_sm4_read_declaration_dst(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst); +} + +static void shader_sm4_read_declaration_register_semantic(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + ins->declaration.register_semantic.sysval_semantic = *tokens; +} + +static void shader_sm4_read_dcl_input_ps(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst); +} + +static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + ins->declaration.register_semantic.sysval_semantic = *tokens; +} + +static void shader_sm4_read_dcl_indexable_temp(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.indexable_temp.register_idx = *tokens++; + ins->declaration.indexable_temp.register_size = *tokens++; + ins->declaration.indexable_temp.component_count = *tokens; +} + +static void shader_sm4_read_dcl_global_flags(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->flags = (opcode_token & WINED3D_SM4_GLOBAL_FLAGS_MASK) >> WINED3D_SM4_GLOBAL_FLAGS_SHIFT; +} + +static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + priv->src_param[0].reg.u.fp_body_idx = *tokens++; + shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_OPAQUE, &priv->src_param[0]); +} + +static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.index = *tokens; +} + +static void shader_sm5_read_dcl_function_table(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.index = *tokens++; + FIXME("Ignoring set of function bodies (count %u).\n", *tokens); +} + +static void shader_sm5_read_dcl_interface(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.fp.index = *tokens++; + ins->declaration.fp.body_count = *tokens++; + ins->declaration.fp.array_size = *tokens >> WINED3D_SM5_FP_ARRAY_SIZE_SHIFT; + ins->declaration.fp.table_count = *tokens++ & WINED3D_SM5_FP_TABLE_COUNT_MASK; + FIXME("Ignoring set of function tables (count %u).\n", ins->declaration.fp.table_count); +} + +static void shader_sm5_read_control_point_count(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.count = (opcode_token & WINED3D_SM5_CONTROL_POINT_COUNT_MASK) + >> WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT; +} + +static void shader_sm5_read_dcl_tessellator_domain(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.tessellator_domain = (opcode_token & WINED3D_SM5_TESSELLATOR_MASK) + >> WINED3D_SM5_TESSELLATOR_SHIFT; +} + +static void shader_sm5_read_dcl_tessellator_partitioning(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.tessellator_partitioning = (opcode_token & WINED3D_SM5_TESSELLATOR_MASK) + >> WINED3D_SM5_TESSELLATOR_SHIFT; +} + +static void shader_sm5_read_dcl_tessellator_output_primitive(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.tessellator_output_primitive = (opcode_token & WINED3D_SM5_TESSELLATOR_MASK) + >> WINED3D_SM5_TESSELLATOR_SHIFT; +} + +static void shader_sm5_read_dcl_hs_max_tessfactor(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.max_tessellation_factor = *(float *)tokens; +} + +static void shader_sm5_read_dcl_thread_group(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->declaration.thread_group_size.x = *tokens++; + ins->declaration.thread_group_size.y = *tokens++; + ins->declaration.thread_group_size.z = *tokens++; +} + +static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.dst); + ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT; +} + +static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.structured_resource.reg); + ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT; + ins->declaration.structured_resource.byte_stride = *tokens; + if (ins->declaration.structured_resource.byte_stride % 4) + FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride); +} + +static void shader_sm5_read_dcl_tgsm_raw(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); + ins->declaration.tgsm_raw.byte_count = *tokens; + if (ins->declaration.tgsm_raw.byte_count % 4) + FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count); +} + +static void shader_sm5_read_dcl_tgsm_structured(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_structured.reg); + ins->declaration.tgsm_structured.byte_stride = *tokens++; + ins->declaration.tgsm_structured.structure_count = *tokens; + if (ins->declaration.tgsm_structured.byte_stride % 4) + FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.tgsm_structured.byte_stride); +} + +static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg); + ins->declaration.structured_resource.byte_stride = *tokens; + if (ins->declaration.structured_resource.byte_stride % 4) + FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride); +} + +static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.dst); +} + +static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins, + DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, + struct wined3d_sm4_data *priv) +{ + ins->flags = (opcode_token & WINED3D_SM5_SYNC_FLAGS_MASK) >> WINED3D_SM5_SYNC_FLAGS_SHIFT; +} + +/* + * f -> WINED3D_DATA_FLOAT + * i -> WINED3D_DATA_INT + * u -> WINED3D_DATA_UINT + * O -> WINED3D_DATA_OPAQUE + * R -> WINED3D_DATA_RESOURCE + * S -> WINED3D_DATA_SAMPLER + * U -> WINED3D_DATA_UAV + */ +static const struct wined3d_sm4_opcode_info opcode_table[] = +{ + {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "f", "ff"}, + {WINED3D_SM4_OP_AND, WINED3DSIH_AND, "u", "uu"}, + {WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, "", ""}, + {WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, "", "u", + shader_sm4_read_conditional_op}, + {WINED3D_SM4_OP_CASE, WINED3DSIH_CASE, "", "u"}, + {WINED3D_SM4_OP_CONTINUE, WINED3DSIH_CONTINUE, "", ""}, + {WINED3D_SM4_OP_CONTINUEC, WINED3DSIH_CONTINUEP, "", "u", + shader_sm4_read_conditional_op}, + {WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, "", ""}, + {WINED3D_SM4_OP_DEFAULT, WINED3DSIH_DEFAULT, "", ""}, + {WINED3D_SM4_OP_DERIV_RTX, WINED3DSIH_DSX, "f", "f"}, + {WINED3D_SM4_OP_DERIV_RTY, WINED3DSIH_DSY, "f", "f"}, + {WINED3D_SM4_OP_DISCARD, WINED3DSIH_TEXKILL, "", "u"}, + {WINED3D_SM4_OP_DIV, WINED3DSIH_DIV, "f", "ff"}, + {WINED3D_SM4_OP_DP2, WINED3DSIH_DP2, "f", "ff"}, + {WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, "f", "ff"}, + {WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, "f", "ff"}, + {WINED3D_SM4_OP_ELSE, WINED3DSIH_ELSE, "", ""}, + {WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, "", ""}, + {WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, "", ""}, + {WINED3D_SM4_OP_ENDLOOP, WINED3DSIH_ENDLOOP, "", ""}, + {WINED3D_SM4_OP_ENDSWITCH, WINED3DSIH_ENDSWITCH, "", ""}, + {WINED3D_SM4_OP_EQ, WINED3DSIH_EQ, "u", "ff"}, + {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, "f", "f"}, + {WINED3D_SM4_OP_FRC, WINED3DSIH_FRC, "f", "f"}, + {WINED3D_SM4_OP_FTOI, WINED3DSIH_FTOI, "i", "f"}, + {WINED3D_SM4_OP_FTOU, WINED3DSIH_FTOU, "u", "f"}, + {WINED3D_SM4_OP_GE, WINED3DSIH_GE, "u", "ff"}, + {WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, "i", "ii"}, + {WINED3D_SM4_OP_IF, WINED3DSIH_IF, "", "u", + shader_sm4_read_conditional_op}, + {WINED3D_SM4_OP_IEQ, WINED3DSIH_IEQ, "u", "ii"}, + {WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, "u", "ii"}, + {WINED3D_SM4_OP_ILT, WINED3DSIH_ILT, "u", "ii"}, + {WINED3D_SM4_OP_IMAD, WINED3DSIH_IMAD, "i", "iii"}, + {WINED3D_SM4_OP_IMAX, WINED3DSIH_IMAX, "i", "ii"}, + {WINED3D_SM4_OP_IMIN, WINED3DSIH_IMIN, "i", "ii"}, + {WINED3D_SM4_OP_IMUL, WINED3DSIH_IMUL, "ii", "ii"}, + {WINED3D_SM4_OP_INE, WINED3DSIH_INE, "u", "ii"}, + {WINED3D_SM4_OP_INEG, WINED3DSIH_INEG, "i", "i"}, + {WINED3D_SM4_OP_ISHL, WINED3DSIH_ISHL, "i", "ii"}, + {WINED3D_SM4_OP_ISHR, WINED3DSIH_ISHR, "i", "ii"}, + {WINED3D_SM4_OP_ITOF, WINED3DSIH_ITOF, "f", "i"}, + {WINED3D_SM4_OP_LABEL, WINED3DSIH_LABEL, "", "O"}, + {WINED3D_SM4_OP_LD, WINED3DSIH_LD, "u", "iR"}, + {WINED3D_SM4_OP_LD2DMS, WINED3DSIH_LD2DMS, "u", "iRi"}, + {WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, "f", "f"}, + {WINED3D_SM4_OP_LOOP, WINED3DSIH_LOOP, "", ""}, + {WINED3D_SM4_OP_LT, WINED3DSIH_LT, "u", "ff"}, + {WINED3D_SM4_OP_MAD, WINED3DSIH_MAD, "f", "fff"}, + {WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, "f", "ff"}, + {WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, "f", "ff"}, + {WINED3D_SM4_OP_SHADER_DATA, WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", + shader_sm4_read_shader_data}, + {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "f", "f"}, + {WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "f", "uff"}, + {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "f", "ff"}, + {WINED3D_SM4_OP_NE, WINED3DSIH_NE, "u", "ff"}, + {WINED3D_SM4_OP_NOT, WINED3DSIH_NOT, "u", "u"}, + {WINED3D_SM4_OP_OR, WINED3DSIH_OR, "u", "uu"}, + {WINED3D_SM4_OP_RESINFO, WINED3DSIH_RESINFO, "f", "iR"}, + {WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""}, + {WINED3D_SM4_OP_RETC, WINED3DSIH_RETP, "", "u", + shader_sm4_read_conditional_op}, + {WINED3D_SM4_OP_ROUND_NE, WINED3DSIH_ROUND_NE, "f", "f"}, + {WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "f", "f"}, + {WINED3D_SM4_OP_ROUND_PI, WINED3DSIH_ROUND_PI, "f", "f"}, + {WINED3D_SM4_OP_ROUND_Z, WINED3DSIH_ROUND_Z, "f", "f"}, + {WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "f", "f"}, + {WINED3D_SM4_OP_SAMPLE, WINED3DSIH_SAMPLE, "u", "fRS"}, + {WINED3D_SM4_OP_SAMPLE_C, WINED3DSIH_SAMPLE_C, "f", "fRSf"}, + {WINED3D_SM4_OP_SAMPLE_C_LZ, WINED3DSIH_SAMPLE_C_LZ, "f", "fRSf"}, + {WINED3D_SM4_OP_SAMPLE_LOD, WINED3DSIH_SAMPLE_LOD, "u", "fRSf"}, + {WINED3D_SM4_OP_SAMPLE_GRAD, WINED3DSIH_SAMPLE_GRAD, "u", "fRSff"}, + {WINED3D_SM4_OP_SAMPLE_B, WINED3DSIH_SAMPLE_B, "u", "fRSf"}, + {WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "f", "f"}, + {WINED3D_SM4_OP_SWITCH, WINED3DSIH_SWITCH, "", "u"}, + {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "ff", "f"}, + {WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "uu", "uu"}, + {WINED3D_SM4_OP_ULT, WINED3DSIH_ULT, "u", "uu"}, + {WINED3D_SM4_OP_UGE, WINED3DSIH_UGE, "u", "uu"}, + {WINED3D_SM4_OP_UMUL, WINED3DSIH_UMUL, "uu", "uu"}, + {WINED3D_SM4_OP_UMAX, WINED3DSIH_UMAX, "u", "uu"}, + {WINED3D_SM4_OP_UMIN, WINED3DSIH_UMIN, "u", "uu"}, + {WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "u", "uu"}, + {WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "f", "u"}, + {WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "u", "uu"}, + {WINED3D_SM4_OP_DCL_RESOURCE, WINED3DSIH_DCL, "R", "", + shader_sm4_read_dcl_resource}, + {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", "", + shader_sm4_read_dcl_constant_buffer}, + {WINED3D_SM4_OP_DCL_SAMPLER, WINED3DSIH_DCL_SAMPLER, "", "", + shader_sm4_read_dcl_sampler}, + {WINED3D_SM4_OP_DCL_INDEX_RANGE, WINED3DSIH_DCL_INDEX_RANGE, "", "", + shader_sm4_read_dcl_index_range}, + {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", + shader_sm4_read_dcl_output_topology}, + {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", "", + shader_sm4_read_dcl_input_primitive}, + {WINED3D_SM4_OP_DCL_VERTICES_OUT, WINED3DSIH_DCL_VERTICES_OUT, "", "", + shader_sm4_read_declaration_count}, + {WINED3D_SM4_OP_DCL_INPUT, WINED3DSIH_DCL_INPUT, "", "", + shader_sm4_read_declaration_dst}, + {WINED3D_SM4_OP_DCL_INPUT_SGV, WINED3DSIH_DCL_INPUT_SGV, "", "", + shader_sm4_read_declaration_register_semantic}, + {WINED3D_SM4_OP_DCL_INPUT_SIV, WINED3DSIH_DCL_INPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {WINED3D_SM4_OP_DCL_INPUT_PS, WINED3DSIH_DCL_INPUT_PS, "", "", + shader_sm4_read_dcl_input_ps}, + {WINED3D_SM4_OP_DCL_INPUT_PS_SGV, WINED3DSIH_DCL_INPUT_PS_SGV, "", "", + shader_sm4_read_declaration_register_semantic}, + {WINED3D_SM4_OP_DCL_INPUT_PS_SIV, WINED3DSIH_DCL_INPUT_PS_SIV, "", "", + shader_sm4_read_dcl_input_ps_siv}, + {WINED3D_SM4_OP_DCL_OUTPUT, WINED3DSIH_DCL_OUTPUT, "", "", + shader_sm4_read_declaration_dst}, + {WINED3D_SM4_OP_DCL_OUTPUT_SIV, WINED3DSIH_DCL_OUTPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {WINED3D_SM4_OP_DCL_TEMPS, WINED3DSIH_DCL_TEMPS, "", "", + shader_sm4_read_declaration_count}, + {WINED3D_SM4_OP_DCL_INDEXABLE_TEMP, WINED3DSIH_DCL_INDEXABLE_TEMP, "", "", + shader_sm4_read_dcl_indexable_temp}, + {WINED3D_SM4_OP_DCL_GLOBAL_FLAGS, WINED3DSIH_DCL_GLOBAL_FLAGS, "", "", + shader_sm4_read_dcl_global_flags}, + {WINED3D_SM4_OP_LOD, WINED3DSIH_LOD, "f", "fRS"}, + {WINED3D_SM4_OP_GATHER4, WINED3DSIH_GATHER4, "u", "fRS"}, + {WINED3D_SM4_OP_SAMPLE_POS, WINED3DSIH_SAMPLE_POS, "f", "Ru"}, + {WINED3D_SM4_OP_SAMPLE_INFO, WINED3DSIH_SAMPLE_INFO, "f", "R"}, + {WINED3D_SM5_OP_HS_DECLS, WINED3DSIH_HS_DECLS, "", ""}, + {WINED3D_SM5_OP_HS_CONTROL_POINT_PHASE, WINED3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, + {WINED3D_SM5_OP_HS_FORK_PHASE, WINED3DSIH_HS_FORK_PHASE, "", ""}, + {WINED3D_SM5_OP_HS_JOIN_PHASE, WINED3DSIH_HS_JOIN_PHASE, "", ""}, + {WINED3D_SM5_OP_EMIT_STREAM, WINED3DSIH_EMIT_STREAM, "", "f"}, + {WINED3D_SM5_OP_CUT_STREAM, WINED3DSIH_CUT_STREAM, "", "f"}, + {WINED3D_SM5_OP_FCALL, WINED3DSIH_FCALL, "", "O", + shader_sm5_read_fcall}, + {WINED3D_SM5_OP_BUFINFO, WINED3DSIH_BUFINFO, "i", "U"}, + {WINED3D_SM5_OP_DERIV_RTX_COARSE, WINED3DSIH_DSX_COARSE, "f", "f"}, + {WINED3D_SM5_OP_DERIV_RTX_FINE, WINED3DSIH_DSX_FINE, "f", "f"}, + {WINED3D_SM5_OP_DERIV_RTY_COARSE, WINED3DSIH_DSY_COARSE, "f", "f"}, + {WINED3D_SM5_OP_DERIV_RTY_FINE, WINED3DSIH_DSY_FINE, "f", "f"}, + {WINED3D_SM5_OP_GATHER4_C, WINED3DSIH_GATHER4_C, "f", "fRSf"}, + {WINED3D_SM5_OP_GATHER4_PO, WINED3DSIH_GATHER4_PO, "f", "fiRS"}, + {WINED3D_SM5_OP_GATHER4_PO_C, WINED3DSIH_GATHER4_PO_C, "f", "fiRSf"}, + {WINED3D_SM5_OP_RCP, WINED3DSIH_RCP, "f", "f"}, + {WINED3D_SM5_OP_F32TOF16, WINED3DSIH_F32TOF16, "u", "f"}, + {WINED3D_SM5_OP_F16TOF32, WINED3DSIH_F16TOF32, "f", "u"}, + {WINED3D_SM5_OP_COUNTBITS, WINED3DSIH_COUNTBITS, "u", "u"}, + {WINED3D_SM5_OP_FIRSTBIT_HI, WINED3DSIH_FIRSTBIT_HI, "u", "u"}, + {WINED3D_SM5_OP_FIRSTBIT_LO, WINED3DSIH_FIRSTBIT_LO, "u", "u"}, + {WINED3D_SM5_OP_FIRSTBIT_SHI, WINED3DSIH_FIRSTBIT_SHI, "u", "i"}, + {WINED3D_SM5_OP_UBFE, WINED3DSIH_UBFE, "u", "iiu"}, + {WINED3D_SM5_OP_IBFE, WINED3DSIH_IBFE, "i", "iii"}, + {WINED3D_SM5_OP_BFI, WINED3DSIH_BFI, "u", "iiuu"}, + {WINED3D_SM5_OP_BFREV, WINED3DSIH_BFREV, "u", "u"}, + {WINED3D_SM5_OP_SWAPC, WINED3DSIH_SWAPC, "ff", "uff"}, + {WINED3D_SM5_OP_DCL_STREAM, WINED3DSIH_DCL_STREAM, "", "O"}, + {WINED3D_SM5_OP_DCL_FUNCTION_BODY, WINED3DSIH_DCL_FUNCTION_BODY, "", "", + shader_sm5_read_dcl_function_body}, + {WINED3D_SM5_OP_DCL_FUNCTION_TABLE, WINED3DSIH_DCL_FUNCTION_TABLE, "", "", + shader_sm5_read_dcl_function_table}, + {WINED3D_SM5_OP_DCL_INTERFACE, WINED3DSIH_DCL_INTERFACE, "", "", + shader_sm5_read_dcl_interface}, + {WINED3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", + shader_sm5_read_control_point_count}, + {WINED3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", + shader_sm5_read_control_point_count}, + {WINED3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, WINED3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", + shader_sm5_read_dcl_tessellator_domain}, + {WINED3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, WINED3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", + shader_sm5_read_dcl_tessellator_partitioning}, + {WINED3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", + shader_sm5_read_dcl_tessellator_output_primitive}, + {WINED3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, WINED3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", + shader_sm5_read_dcl_hs_max_tessfactor}, + {WINED3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", + shader_sm4_read_declaration_count}, + {WINED3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", + shader_sm4_read_declaration_count}, + {WINED3D_SM5_OP_DCL_THREAD_GROUP, WINED3DSIH_DCL_THREAD_GROUP, "", "", + shader_sm5_read_dcl_thread_group}, + {WINED3D_SM5_OP_DCL_UAV_TYPED, WINED3DSIH_DCL_UAV_TYPED, "", "", + shader_sm4_read_dcl_resource}, + {WINED3D_SM5_OP_DCL_UAV_RAW, WINED3DSIH_DCL_UAV_RAW, "", "", + shader_sm5_read_dcl_uav_raw}, + {WINED3D_SM5_OP_DCL_UAV_STRUCTURED, WINED3DSIH_DCL_UAV_STRUCTURED, "", "", + shader_sm5_read_dcl_uav_structured}, + {WINED3D_SM5_OP_DCL_TGSM_RAW, WINED3DSIH_DCL_TGSM_RAW, "", "", + shader_sm5_read_dcl_tgsm_raw}, + {WINED3D_SM5_OP_DCL_TGSM_STRUCTURED, WINED3DSIH_DCL_TGSM_STRUCTURED, "", "", + shader_sm5_read_dcl_tgsm_structured}, + {WINED3D_SM5_OP_DCL_RESOURCE_RAW, WINED3DSIH_DCL_RESOURCE_RAW, "", "", + shader_sm5_read_dcl_resource_raw}, + {WINED3D_SM5_OP_DCL_RESOURCE_STRUCTURED, WINED3DSIH_DCL_RESOURCE_STRUCTURED, "", "", + shader_sm5_read_dcl_resource_structured}, + {WINED3D_SM5_OP_LD_UAV_TYPED, WINED3DSIH_LD_UAV_TYPED, "u", "iU"}, + {WINED3D_SM5_OP_STORE_UAV_TYPED, WINED3DSIH_STORE_UAV_TYPED, "U", "iu"}, + {WINED3D_SM5_OP_LD_RAW, WINED3DSIH_LD_RAW, "u", "iU"}, + {WINED3D_SM5_OP_STORE_RAW, WINED3DSIH_STORE_RAW, "U", "iu"}, + {WINED3D_SM5_OP_LD_STRUCTURED, WINED3DSIH_LD_STRUCTURED, "u", "iiR"}, + {WINED3D_SM5_OP_STORE_STRUCTURED, WINED3DSIH_STORE_STRUCTURED, "U", "iiu"}, + {WINED3D_SM5_OP_ATOMIC_AND, WINED3DSIH_ATOMIC_AND, "U", "iu"}, + {WINED3D_SM5_OP_ATOMIC_OR, WINED3DSIH_ATOMIC_OR, "U", "iu"}, + {WINED3D_SM5_OP_ATOMIC_XOR, WINED3DSIH_ATOMIC_XOR, "U", "iu"}, + {WINED3D_SM5_OP_ATOMIC_CMP_STORE, WINED3DSIH_ATOMIC_CMP_STORE, "U", "iuu"}, + {WINED3D_SM5_OP_ATOMIC_IADD, WINED3DSIH_ATOMIC_IADD, "U", "ii"}, + {WINED3D_SM5_OP_ATOMIC_IMAX, WINED3DSIH_ATOMIC_IMAX, "U", "ii"}, + {WINED3D_SM5_OP_ATOMIC_IMIN, WINED3DSIH_ATOMIC_IMIN, "U", "ii"}, + {WINED3D_SM5_OP_ATOMIC_UMAX, WINED3DSIH_ATOMIC_UMAX, "U", "iu"}, + {WINED3D_SM5_OP_ATOMIC_UMIN, WINED3DSIH_ATOMIC_UMIN, "U", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_ALLOC, WINED3DSIH_IMM_ATOMIC_ALLOC, "u", "U"}, + {WINED3D_SM5_OP_IMM_ATOMIC_CONSUME, WINED3DSIH_IMM_ATOMIC_CONSUME, "u", "U"}, + {WINED3D_SM5_OP_IMM_ATOMIC_IADD, WINED3DSIH_IMM_ATOMIC_IADD, "uU", "ii"}, + {WINED3D_SM5_OP_IMM_ATOMIC_AND, WINED3DSIH_IMM_ATOMIC_AND, "uU", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_OR, WINED3DSIH_IMM_ATOMIC_OR, "uU", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_XOR, WINED3DSIH_IMM_ATOMIC_XOR, "uU", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_EXCH, WINED3DSIH_IMM_ATOMIC_EXCH, "uU", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, WINED3DSIH_IMM_ATOMIC_CMP_EXCH, "uU", "iuu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_IMAX, WINED3DSIH_IMM_ATOMIC_IMAX, "iU", "ii"}, + {WINED3D_SM5_OP_IMM_ATOMIC_IMIN, WINED3DSIH_IMM_ATOMIC_IMIN, "iU", "ii"}, + {WINED3D_SM5_OP_IMM_ATOMIC_UMAX, WINED3DSIH_IMM_ATOMIC_UMAX, "uU", "iu"}, + {WINED3D_SM5_OP_IMM_ATOMIC_UMIN, WINED3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, + {WINED3D_SM5_OP_SYNC, WINED3DSIH_SYNC, "", "", + shader_sm5_read_sync}, + {WINED3D_SM5_OP_DCL_GS_INSTANCES, WINED3DSIH_DCL_GS_INSTANCES, "", "", + shader_sm4_read_declaration_count}, +}; + +static const enum wined3d_shader_register_type register_type_table[] = +{ + /* WINED3D_SM4_RT_TEMP */ WINED3DSPR_TEMP, + /* WINED3D_SM4_RT_INPUT */ WINED3DSPR_INPUT, + /* WINED3D_SM4_RT_OUTPUT */ WINED3DSPR_OUTPUT, + /* WINED3D_SM4_RT_INDEXABLE_TEMP */ WINED3DSPR_IDXTEMP, + /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST, + /* UNKNOWN */ ~0u, + /* WINED3D_SM4_RT_SAMPLER */ WINED3DSPR_SAMPLER, + /* WINED3D_SM4_RT_RESOURCE */ WINED3DSPR_RESOURCE, + /* WINED3D_SM4_RT_CONSTBUFFER */ WINED3DSPR_CONSTBUFFER, + /* WINED3D_SM4_RT_IMMCONSTBUFFER */ WINED3DSPR_IMMCONSTBUFFER, + /* UNKNOWN */ ~0u, + /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID, + /* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT, + /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL, + /* UNKNOWN */ ~0u, + /* WINED3D_SM4_RT_OMASK */ WINED3DSPR_SAMPLEMASK, + /* WINED3D_SM5_RT_STREAM */ WINED3DSPR_STREAM, + /* WINED3D_SM5_RT_FUNCTION_BODY */ WINED3DSPR_FUNCTIONBODY, + /* UNKNOWN */ ~0u, + /* WINED3D_SM5_RT_FUNCTION_POINTER */ WINED3DSPR_FUNCTIONPOINTER, + /* UNKNOWN */ ~0u, + /* UNKNOWN */ ~0u, + /* WINED3D_SM5_RT_OUTPUT_CONTROL_POINT_ID */ WINED3DSPR_OUTPOINTID, + /* WINED3D_SM5_RT_FORK_INSTANCE_ID */ WINED3DSPR_FORKINSTID, + /* WINED3D_SM5_RT_JOIN_INSTANCE_ID */ WINED3DSPR_JOININSTID, + /* WINED3D_SM5_RT_INPUT_CONTROL_POINT */ WINED3DSPR_INCONTROLPOINT, + /* WINED3D_SM5_RT_OUTPUT_CONTROL_POINT */ WINED3DSPR_OUTCONTROLPOINT, + /* WINED3D_SM5_RT_PATCH_CONSTANT_DATA */ WINED3DSPR_PATCHCONST, + /* WINED3D_SM5_RT_DOMAIN_LOCATION */ WINED3DSPR_TESSCOORD, + /* UNKNOWN */ ~0u, + /* WINED3D_SM5_RT_UAV */ WINED3DSPR_UAV, + /* WINED3D_SM5_RT_SHARED_MEMORY */ WINED3DSPR_GROUPSHAREDMEM, + /* WINED3D_SM5_RT_THREAD_ID */ WINED3DSPR_THREADID, + /* WINED3D_SM5_RT_THREAD_GROUP_ID */ WINED3DSPR_THREADGROUPID, + /* WINED3D_SM5_RT_LOCAL_THREAD_ID */ WINED3DSPR_LOCALTHREADID, + /* WINED3D_SM5_RT_COVERAGE */ WINED3DSPR_COVERAGE, + /* WINED3D_SM5_RT_LOCAL_THREAD_INDEX */ WINED3DSPR_LOCALTHREADINDEX, + /* WINED3D_SM5_RT_GS_INSTANCE_ID */ WINED3DSPR_GSINSTID, +}; static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode) { @@ -493,8 +1166,8 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha break; } - reg->type = priv->output_map[reg_idx].register_type; - reg->idx[0].offset = priv->output_map[reg_idx].register_idx; + reg->type = WINED3DSPR_COLOROUT; + reg->idx[0].offset = priv->output_map[reg_idx]; } break; @@ -507,26 +1180,49 @@ static enum wined3d_data_type map_data_type(char t) { switch (t) { - case 'F': + case 'f': return WINED3D_DATA_FLOAT; - case 'I': + case 'i': return WINED3D_DATA_INT; + case 'u': + return WINED3D_DATA_UINT; + case 'O': + return WINED3D_DATA_OPAQUE; case 'R': return WINED3D_DATA_RESOURCE; case 'S': return WINED3D_DATA_SAMPLER; case 'U': - return WINED3D_DATA_UINT; + return WINED3D_DATA_UAV; default: ERR("Invalid data type '%c'.\n", t); return WINED3D_DATA_FLOAT; } } -static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature) +static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, + const struct wined3d_shader_signature *output_signature) { + DWORD version_token, token_count; struct wined3d_sm4_data *priv; - unsigned int i, j; + unsigned int i; + + if (byte_code_size / sizeof(*byte_code) < 2) + { + WARN("Invalid byte code size %lu.\n", (long)byte_code_size); + return NULL; + } + + version_token = byte_code[0]; + TRACE("Version: 0x%08x.\n", version_token); + token_count = byte_code[1]; + TRACE("Token count: %u.\n", token_count); + + if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count) + { + WARN("Invalid token count %u.\n", token_count); + return NULL; + } if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)))) { @@ -534,6 +1230,41 @@ static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader return NULL; } + priv->start = &byte_code[2]; + priv->end = &byte_code[token_count]; + + switch (version_token >> 16) + { + case WINED3D_SM4_PS: + priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL; + break; + + case WINED3D_SM4_VS: + priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX; + break; + + case WINED3D_SM4_GS: + priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; + break; + + case WINED3D_SM5_HS: + priv->shader_version.type = WINED3D_SHADER_TYPE_HULL; + break; + + case WINED3D_SM5_DS: + priv->shader_version.type = WINED3D_SHADER_TYPE_DOMAIN; + break; + + case WINED3D_SM5_CS: + priv->shader_version.type = WINED3D_SHADER_TYPE_COMPUTE; + break; + + default: + FIXME("Unrecognised shader type %#x.\n", version_token >> 16); + } + priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token); + priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token); + memset(priv->output_map, 0xff, sizeof(priv->output_map)); for (i = 0; i < output_signature->element_count; ++i) { @@ -545,15 +1276,7 @@ static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader continue; } - for (j = 0; j < ARRAY_SIZE(sysval_map); ++j) - { - if (e->sysval_semantic == sysval_map[j].sysval) - { - priv->output_map[e->register_idx].register_type = sysval_map[j].register_type; - priv->output_map[e->register_idx].register_idx = sysval_map[j].register_idx; - break; - } - } + priv->output_map[e->register_idx] = e->semantic_idx; } list_init(&priv->src_free); @@ -600,36 +1323,8 @@ static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *p static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version) { struct wined3d_sm4_data *priv = data; - DWORD version_token; - - priv->end = *ptr; - - version_token = *(*ptr)++; - TRACE("version: 0x%08x\n", version_token); - - TRACE("token count: %u\n", **ptr); - priv->end += *(*ptr)++; - - switch (version_token >> 16) - { - case WINED3D_SM4_PS: - priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL; - break; - - case WINED3D_SM4_VS: - priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX; - break; - - case WINED3D_SM4_GS: - priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY; - break; - - default: - FIXME("Unrecognized shader type %#x\n", version_token >> 16); - } - priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token); - priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token); + *ptr = priv->start; *shader_version = priv->shader_version; } @@ -670,7 +1365,8 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p DWORD order; register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT; - if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table)) + if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table) + || register_type_table[register_type] == ~0u) { FIXME("Unhandled register type %#x.\n", register_type); param->type = WINED3DSPR_TEMP; @@ -748,13 +1444,13 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p { case WINED3D_SM4_IMMCONST_SCALAR: param->immconst_type = WINED3D_IMMCONST_SCALAR; - memcpy(param->immconst_data, *ptr, 1 * sizeof(DWORD)); + memcpy(param->u.immconst_data, *ptr, 1 * sizeof(DWORD)); *ptr += 1; break; case WINED3D_SM4_IMMCONST_VEC4: param->immconst_type = WINED3D_IMMCONST_VEC4; - memcpy(param->immconst_data, *ptr, 4 * sizeof(DWORD)); + memcpy(param->u.immconst_data, *ptr, 4 * sizeof(DWORD)); *ptr += 4; break; @@ -838,22 +1534,73 @@ static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD return TRUE; } +static void shader_sm4_read_instruction_modifier(DWORD modifier, struct wined3d_shader_instruction *ins) +{ + static const DWORD recognized_bits = WINED3D_SM4_INSTRUCTION_MODIFIER + | WINED3D_SM4_MODIFIER_AOFFIMMI + | WINED3D_SM4_AOFFIMMI_U_MASK + | WINED3D_SM4_AOFFIMMI_V_MASK + | WINED3D_SM4_AOFFIMMI_W_MASK; + + if (modifier & ~recognized_bits) + { + FIXME("Unhandled modifier 0x%08x.\n", modifier); + } + else + { + /* Bit fields are used for sign extension */ + struct + { + int u : 4; + int v : 4; + int w : 4; + } + aoffimmi; + aoffimmi.u = (modifier & WINED3D_SM4_AOFFIMMI_U_MASK) >> WINED3D_SM4_AOFFIMMI_U_SHIFT; + aoffimmi.v = (modifier & WINED3D_SM4_AOFFIMMI_V_MASK) >> WINED3D_SM4_AOFFIMMI_V_SHIFT; + aoffimmi.w = (modifier & WINED3D_SM4_AOFFIMMI_W_MASK) >> WINED3D_SM4_AOFFIMMI_W_SHIFT; + ins->texel_offset.u = aoffimmi.u; + ins->texel_offset.v = aoffimmi.v; + ins->texel_offset.w = aoffimmi.w; + } +} + static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins) { const struct wined3d_sm4_opcode_info *opcode_info; + DWORD opcode_token, opcode, previous_token; struct wined3d_sm4_data *priv = data; - DWORD opcode_token, opcode; + unsigned int i, len; + SIZE_T remaining; const DWORD *p; - UINT i, len; list_move_head(&priv->src_free, &priv->src); + if (*ptr >= priv->end) + { + WARN("End of byte-code, failed to read opcode.\n"); + goto fail; + } + remaining = priv->end - *ptr; + opcode_token = *(*ptr)++; opcode = opcode_token & WINED3D_SM4_OPCODE_MASK; len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT); if (!len) + { + if (remaining < 2) + { + WARN("End of byte-code, failed to read length token.\n"); + goto fail; + } len = **ptr; + } + if (!len || remaining < len) + { + WARN("Read invalid length %u (remaining %lu).\n", len, remaining); + goto fail; + } --len; if (TRACE_ON(d3d_bytecode)) @@ -882,155 +1629,23 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi ins->dst = priv->dst_param; ins->src_count = strlen(opcode_info->src_info); ins->src = priv->src_param; + memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); p = *ptr; *ptr += len; - if (opcode_token & WINED3D_SM4_INSTRUCTION_MODIFIER) + if (opcode_info->read_opcode_func) { - DWORD modifier = *p++; - FIXME("Skipping modifier 0x%08x.\n", modifier); - } - - if (opcode == WINED3D_SM4_OP_SHADER_DATA) - { - unsigned int icb_size; - enum wined3d_sm4_shader_data_type type; - - type = (opcode_token & WINED3D_SM4_SHADER_DATA_TYPE_MASK) >> WINED3D_SM4_SHADER_DATA_TYPE_SHIFT; - if (type != WINED3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) - { - FIXME("Unhandled shader data type %#x.\n", type); - ins->handler_idx = WINED3DSIH_TABLE_SIZE; - return; - } - - ++p; - icb_size = len - 1; - if (icb_size % 4 || icb_size > MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE) - { - FIXME("Unexpected immediate constant buffer size %u.\n", len); - ins->handler_idx = WINED3DSIH_TABLE_SIZE; - return; - } - - priv->icb.element_count = len; - memcpy(priv->icb.data, p, sizeof(*p) * icb_size); - ins->declaration.icb = &priv->icb; - } - else if (opcode == WINED3D_SM4_OP_DCL_RESOURCE) - { - enum wined3d_sm4_resource_type resource_type; - enum wined3d_sm4_data_type data_type; - DWORD components; - - resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT; - if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table))) - { - FIXME("Unhandled resource type %#x.\n", resource_type); - ins->declaration.semantic.resource_type = WINED3D_SHADER_RESOURCE_NONE; - } - else - { - ins->declaration.semantic.resource_type = resource_type_table[resource_type]; - } - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_RESOURCE, &ins->declaration.semantic.reg); - - components = *p++; - if ((components & 0xfff0) != (components & 0xf) * 0x1110) - FIXME("Components (%#x) have different data types.\n", components); - data_type = components & 0xf; - - if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) - { - FIXME("Unhandled data type %#x.\n", data_type); - ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT; - } - else - { - ins->declaration.semantic.resource_data_type = data_type_table[data_type]; - } - } - else if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER) - { - shader_sm4_read_src_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.src); - if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK) - ins->flags |= WINED3DSI_INDEXED_DYNAMIC; - } - else if (opcode == WINED3D_SM4_OP_DCL_SAMPLER) - { - ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT; - if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON) - FIXME("Unhandled sampler mode %#x.\n", ins->flags); - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_SAMPLER, &ins->declaration.dst); - } - else if (opcode == WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY) - { - enum wined3d_sm4_output_primitive_type primitive_type; - - primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT; - if (primitive_type >= sizeof(output_primitive_type_table) / sizeof(*output_primitive_type_table)) - { - FIXME("Unhandled output primitive type %#x.\n", primitive_type); - ins->declaration.primitive_type = WINED3D_PT_UNDEFINED; - } - else - { - ins->declaration.primitive_type = output_primitive_type_table[primitive_type]; - } - } - else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE) - { - enum wined3d_sm4_input_primitive_type primitive_type; - - primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT; - if (primitive_type >= sizeof(input_primitive_type_table) / sizeof(*input_primitive_type_table)) - { - FIXME("Unhandled input primitive type %#x.\n", primitive_type); - ins->declaration.primitive_type = WINED3D_PT_UNDEFINED; - } - else - { - ins->declaration.primitive_type = input_primitive_type_table[primitive_type]; - } - } - else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS) - { - ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.dst); - } - else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS_SGV - || opcode == WINED3D_SM4_OP_DCL_INPUT_SGV - || opcode == WINED3D_SM4_OP_DCL_INPUT_SIV - || opcode == WINED3D_SM4_OP_DCL_OUTPUT_SIV) - { - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); - ins->declaration.register_semantic.sysval_semantic = *p++; - } - else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS_SIV) - { - ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); - ins->declaration.register_semantic.sysval_semantic = *p++; - } - else if (opcode == WINED3D_SM4_OP_DCL_INPUT - || opcode == WINED3D_SM4_OP_DCL_OUTPUT) - { - shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.dst); - } - else if (opcode == WINED3D_SM4_OP_DCL_VERTICES_OUT - || opcode == WINED3D_SM4_OP_DCL_TEMPS) - { - ins->declaration.count = *p++; - } - else if (opcode == WINED3D_SM4_OP_DCL_GLOBAL_FLAGS) - { - ins->flags = (opcode_token & WINED3D_SM4_GLOBAL_FLAGS_MASK) >> WINED3D_SM4_GLOBAL_FLAGS_SHIFT; + opcode_info->read_opcode_func(ins, opcode, opcode_token, p, len, priv); } else { enum wined3d_shader_dst_modifier instruction_dst_modifier = WINED3DSPDM_NONE; + previous_token = opcode_token; + while (previous_token & WINED3D_SM4_INSTRUCTION_MODIFIER && p != *ptr) + shader_sm4_read_instruction_modifier(previous_token = *p++, ins); + ins->flags = (opcode_token & WINED3D_SM4_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT; if (ins->flags & WINED3D_SM4_INSTRUCTION_FLAG_SATURATE) @@ -1058,6 +1673,13 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi } } } + + return; + +fail: + *ptr = priv->end; + ins->handler_idx = WINED3DSIH_TABLE_SIZE; + return; } static BOOL shader_sm4_is_end(void *data, const DWORD **ptr) diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index b49cf00602b..36fc877d67e 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -30,11 +30,71 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); +ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state) +{ + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + return refcount; +} + +static void wined3d_rasterizer_state_destroy_object(void *object) +{ + HeapFree(GetProcessHeap(), 0, object); +} + +ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state) +{ + ULONG refcount = InterlockedDecrement(&state->refcount); + struct wined3d_device *device = state->device; + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + state->parent_ops->wined3d_object_destroyed(state->parent); + wined3d_cs_destroy_object(device->cs, wined3d_rasterizer_state_destroy_object, state); + } + + return refcount; +} + +void * CDECL wined3d_rasterizer_state_get_parent(const struct wined3d_rasterizer_state *state) +{ + TRACE("rasterizer_state %p.\n", state); + + return state->parent; +} + +HRESULT CDECL wined3d_rasterizer_state_create(struct wined3d_device *device, + const struct wined3d_rasterizer_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_rasterizer_state **state) +{ + struct wined3d_rasterizer_state *object; + + TRACE("device %p, desc %p, state %p.\n", device, desc, state); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->refcount = 1; + object->desc = *desc; + object->parent = parent; + object->parent_ops = parent_ops; + object->device = device; + + TRACE("Created rasterizer state %p.\n", object); + *state = object; + + return WINED3D_OK; +} + /* Context activation for state handler is done by the caller. */ static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - ERR("Undefined state.\n"); + ERR("Undefined state %s (%#x).\n", debug_d3dstate(state_id), state_id); } void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -97,11 +157,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ const struct wined3d_gl_info *gl_info = context->gl_info; /* No z test without depth stencil buffers */ -#if defined(STAGING_CSMT) - if (!state->fb.depth_stencil) -#else /* STAGING_CSMT */ if (!state->fb->depth_stencil) -#endif /* STAGING_CSMT */ { TRACE("No Z buffer - disabling depth test\n"); zenable = WINED3D_ZB_FALSE; @@ -143,13 +199,13 @@ static void state_cullmode(struct wined3d_context *context, const struct wined3d gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); checkGLcall("glDisable GL_CULL_FACE"); break; - case WINED3D_CULL_CW: + case WINED3D_CULL_FRONT: gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE); checkGLcall("glEnable GL_CULL_FACE"); gl_info->gl_ops.gl.p_glCullFace(GL_FRONT); checkGLcall("glCullFace(GL_FRONT)"); break; - case WINED3D_CULL_CCW: + case WINED3D_CULL_BACK: gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE); checkGLcall("glEnable GL_CULL_FACE"); gl_info->gl_ops.gl.p_glCullFace(GL_BACK); @@ -200,7 +256,7 @@ static void state_ditherenable(struct wined3d_context *context, const struct win } } -static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_zwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -259,11 +315,11 @@ static void state_zfunc(struct wined3d_context *context, const struct wined3d_st static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_color color; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col); - TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]); - gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_AMBIENT]); + TRACE("Setting ambient to %s.\n", debug_color(&color)); + gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &color.r); checkGLcall("glLightModel for MODEL_AMBIENT"); } @@ -287,7 +343,10 @@ static GLenum gl_blend_op(const struct wined3d_gl_info *gl_info, enum wined3d_bl case WINED3D_BLEND_OP_MAX: return gl_info->supported[EXT_BLEND_MINMAX] ? GL_MAX : GL_FUNC_ADD; default: - FIXME("Unhandled blend op %#x.\n", op); + if (!op) + WARN("Unhandled blend op %#x.\n", op); + else + FIXME("Unhandled blend op %#x.\n", op); return GL_FUNC_ADD; } } @@ -358,92 +417,81 @@ static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_fo return GL_CONSTANT_COLOR_EXT; case WINED3D_BLEND_INVBLENDFACTOR: return GL_ONE_MINUS_CONSTANT_COLOR_EXT; + case WINED3D_BLEND_SRC1COLOR: + return GL_SRC1_COLOR; + case WINED3D_BLEND_INVSRC1COLOR: + return GL_ONE_MINUS_SRC1_COLOR; + case WINED3D_BLEND_SRC1ALPHA: + return GL_SRC1_ALPHA; + case WINED3D_BLEND_INVSRC1ALPHA: + return GL_ONE_MINUS_SRC1_ALPHA; default: - { - static int once; - if (factor || !once++) FIXME("Unhandled blend factor %#x.\n", factor); + if (!factor) + WARN("Unhandled blend factor %#x.\n", factor); + else + FIXME("Unhandled blend factor %#x.\n", factor); return GL_NONE; - } + } +} + +static void gl_blend_from_d3d(GLenum *src_blend, GLenum *dst_blend, + enum wined3d_blend d3d_src_blend, enum wined3d_blend d3d_dst_blend, + const struct wined3d_format *rt_format) +{ + /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy + * source blending values which are still valid up to d3d9. They should + * not occur as dest blend values. */ + if (d3d_src_blend == WINED3D_BLEND_BOTHSRCALPHA) + { + *src_blend = GL_SRC_ALPHA; + *dst_blend = GL_ONE_MINUS_SRC_ALPHA; + } + else if (d3d_src_blend == WINED3D_BLEND_BOTHINVSRCALPHA) + { + *src_blend = GL_ONE_MINUS_SRC_ALPHA; + *dst_blend = GL_SRC_ALPHA; + } + else + { + *src_blend = gl_blend_factor(d3d_src_blend, rt_format); + *dst_blend = gl_blend_factor(d3d_dst_blend, rt_format); } } static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) - const struct wined3d_format *rt_format = state->fb.render_targets[0]->format; - unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; -#else /* STAGING_CSMT */ - const struct wined3d_format *rt_format = state->fb->render_targets[0]->format; - unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -#endif /* STAGING_CSMT */ const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum srcBlend, dstBlend; - enum wined3d_blend d3d_blend; + const struct wined3d_format *rt_format; + GLenum src_blend, dst_blend; + unsigned int rt_fmt_flags; + BOOL enable_blend; - /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific - * blending parameters to work. */ - if (state->render_states[WINED3D_RS_ALPHABLENDENABLE] - || state->render_states[WINED3D_RS_EDGEANTIALIAS] - || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE]) + enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE]; + if (enable_blend) { + rt_format = state->fb->render_targets[0]->format; + rt_fmt_flags = state->fb->render_targets[0]->format_flags; + /* Disable blending in all cases even without pixelshaders. * With blending on we could face a big performance penalty. * The d3d9 visual test confirms the behavior. */ if (context->render_offscreen && !(rt_fmt_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) - { - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - return; - } - else - { - gl_info->gl_ops.gl.p_glEnable(GL_BLEND); - checkGLcall("glEnable GL_BLEND"); - } + enable_blend = FALSE; } - else + + if (!enable_blend) { gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - /* Nothing more to do - get out */ + checkGLcall("glDisable(GL_BLEND)"); return; - }; - - /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy - * source blending values which are still valid up to d3d9. They should - * not occur as dest blend values. */ - d3d_blend = state->render_states[WINED3D_RS_SRCBLEND]; - if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA) - { - srcBlend = GL_SRC_ALPHA; - dstBlend = GL_ONE_MINUS_SRC_ALPHA; - } - else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA) - { - srcBlend = GL_ONE_MINUS_SRC_ALPHA; - dstBlend = GL_SRC_ALPHA; - } - else - { - srcBlend = gl_blend_factor(d3d_blend, rt_format); - dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND], rt_format); } - if (state->render_states[WINED3D_RS_EDGEANTIALIAS] - || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE]) - { - gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH); - checkGLcall("glEnable(GL_LINE_SMOOTH)"); - if (srcBlend != GL_SRC_ALPHA) - WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n"); - if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) - WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n"); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH); - checkGLcall("glDisable(GL_LINE_SMOOTH)"); - } + gl_info->gl_ops.gl.p_glEnable(GL_BLEND); + checkGLcall("glEnable(GL_BLEND)"); + + gl_blend_from_d3d(&src_blend, &dst_blend, + state->render_states[WINED3D_RS_SRCBLEND], + state->render_states[WINED3D_RS_DESTBLEND], rt_format); /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP))) @@ -451,7 +499,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE]) { - GLenum srcBlendAlpha, dstBlendAlpha; + GLenum src_blend_alpha, dst_blend_alpha; /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */ if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) @@ -460,33 +508,17 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st return; } - /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy - * source blending values which are still valid up to d3d9. They should - * not occur as dest blend values. */ - d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA]; - if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA) - { - srcBlendAlpha = GL_SRC_ALPHA; - dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - } - else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA) - { - srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - dstBlendAlpha = GL_SRC_ALPHA; - } - else - { - srcBlendAlpha = gl_blend_factor(d3d_blend, rt_format); - dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA], rt_format); - } + gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, + state->render_states[WINED3D_RS_SRCBLENDALPHA], + state->render_states[WINED3D_RS_DESTBLENDALPHA], rt_format); - GL_EXTCALL(glBlendFuncSeparate(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha)); + GL_EXTCALL(glBlendFuncSeparate(src_blend, dst_blend, src_blend_alpha, dst_blend_alpha)); checkGLcall("glBlendFuncSeparate"); } else { - TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend); - gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend); + TRACE("glBlendFunc src=%x, dst=%x.\n", src_blend, dst_blend); + gl_info->gl_ops.gl.p_glBlendFunc(src_blend, dst_blend); checkGLcall("glBlendFunc"); } @@ -504,12 +536,12 @@ static void state_blendfactor_w(struct wined3d_context *context, const struct wi static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_color color; TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]); - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col); - GL_EXTCALL(glBlendColor(col[0], col[1], col[2], col[3])); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_BLENDFACTOR]); + GL_EXTCALL(glBlendColor(color.r, color.g, color.b, color.a)); checkGLcall("glBlendColor"); } @@ -572,8 +604,8 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - DWORD enable = 0xffffffff; - DWORD disable = 0x00000000; + unsigned int clipplane_count = gl_info->limits.user_clip_distances; + unsigned int i, enable_mask, disable_mask; if (use_vs(state) && !context->d3d_info->vs_clipping) { @@ -605,29 +637,29 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state */ if (state->render_states[WINED3D_RS_CLIPPING]) { - enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE]; - disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE]; + enable_mask = state->render_states[WINED3D_RS_CLIPPLANEENABLE]; + disable_mask = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE]; } else { - disable = 0xffffffff; - enable = 0x00; + enable_mask = 0; + disable_mask = ~0u; } - if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0); - if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1); - if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2); - if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3); - if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4); - if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5); + if (clipplane_count < 32) + { + enable_mask &= (1u << clipplane_count) - 1; + disable_mask &= (1u << clipplane_count) - 1; + } + + for (i = 0; enable_mask && i < clipplane_count; enable_mask >>= 1, ++i) + if (enable_mask & 1) + gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i); checkGLcall("clip plane enable"); - if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0); - if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1); - if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2); - if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3); - if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4); - if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); + for (i = 0; disable_mask && i < clipplane_count; disable_mask >>= 1, ++i) + if (disable_mask & 1) + gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i); checkGLcall("clip plane disable"); } @@ -719,18 +751,10 @@ static void state_specularenable(struct wined3d_context *context, const struct w } } - TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n", - state->material.diffuse.r, state->material.diffuse.g, - state->material.diffuse.b, state->material.diffuse.a); - TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n", - state->material.ambient.r, state->material.ambient.g, - state->material.ambient.b, state->material.ambient.a); - TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n", - state->material.specular.r, state->material.specular.g, - state->material.specular.b, state->material.specular.a); - TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n", - state->material.emissive.r, state->material.emissive.g, - state->material.emissive.b, state->material.emissive.a); + TRACE("diffuse %s\n", debug_color(&state->material.diffuse)); + TRACE("ambient %s\n", debug_color(&state->material.ambient)); + TRACE("specular %s\n", debug_color(&state->material.specular)); + TRACE("emissive %s\n", debug_color(&state->material.emissive)); gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient); checkGLcall("glMaterialfv(GL_AMBIENT)"); @@ -743,12 +767,12 @@ static void state_specularenable(struct wined3d_context *context, const struct w static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_color color; unsigned int i; /* Note the texture color applies to all textures whereas * GL_TEXTURE_ENV_COLOR applies to active only. */ - float col[4]; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); /* And now the default texture color as well */ for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i) @@ -757,7 +781,7 @@ static void state_texfactor(struct wined3d_context *context, const struct wined3 * per texture, so apply it now ready to be used! */ context_active_texture(context, gl_info, i); - gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]); + gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color.r); checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);"); } } @@ -798,7 +822,10 @@ static GLenum gl_stencil_op(enum wined3d_stencil_op op) case WINED3D_STENCIL_OP_DECR: return GL_DECR_WRAP; default: - FIXME("Unrecognized stencil op %#x.\n", op); + if (!op) + WARN("Unrecognized stencil op %#x.\n", op); + else + FIXME("Unrecognized stencil op %#x.\n", op); return GL_KEEP; } } @@ -809,22 +836,18 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ DWORD onesided_enable; DWORD twosided_enable; GLint func; - GLint func_ccw; + GLint func_back; GLint ref; GLuint mask; GLint stencilFail; - GLint stencilFail_ccw; + GLint stencilFail_back; GLint stencilPass; - GLint stencilPass_ccw; + GLint stencilPass_back; GLint depthFail; - GLint depthFail_ccw; + GLint depthFail_back; /* No stencil test without a stencil buffer. */ -#if defined(STAGING_CSMT) - if (!state->fb.depth_stencil) -#else /* STAGING_CSMT */ if (!state->fb->depth_stencil) -#endif /* STAGING_CSMT */ { gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); @@ -835,23 +858,23 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE]; if (!(func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC]))) func = GL_ALWAYS; - if (!(func_ccw = wined3d_gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC]))) - func_ccw = GL_ALWAYS; + if (!(func_back = wined3d_gl_compare_func(state->render_states[WINED3D_RS_BACK_STENCILFUNC]))) + func_back = GL_ALWAYS; ref = state->render_states[WINED3D_RS_STENCILREF]; mask = state->render_states[WINED3D_RS_STENCILMASK]; stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]); depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]); stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]); - stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]); - depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]); - stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]); + stencilFail_back = gl_stencil_op(state->render_states[WINED3D_RS_BACK_STENCILFAIL]); + depthFail_back = gl_stencil_op(state->render_states[WINED3D_RS_BACK_STENCILZFAIL]); + stencilPass_back = gl_stencil_op(state->render_states[WINED3D_RS_BACK_STENCILPASS]); TRACE("(onesided %d, twosided %d, ref %x, mask %x, " - "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x " - "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n", - onesided_enable, twosided_enable, ref, mask, - func, stencilFail, depthFail, stencilPass, - func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw); + "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x " + "GL_BACK: func: %x, fail %x, zfail %x, zpass %x)\n", + onesided_enable, twosided_enable, ref, mask, + func, stencilFail, depthFail, stencilPass, + func_back, stencilFail_back, depthFail_back, stencilPass_back); if (twosided_enable && onesided_enable) { @@ -862,8 +885,8 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ { GL_EXTCALL(glStencilFuncSeparate(GL_FRONT, func, ref, mask)); GL_EXTCALL(glStencilOpSeparate(GL_FRONT, stencilFail, depthFail, stencilPass)); - GL_EXTCALL(glStencilFuncSeparate(GL_BACK, func_ccw, ref, mask)); - GL_EXTCALL(glStencilOpSeparate(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw)); + GL_EXTCALL(glStencilFuncSeparate(GL_BACK, func_back, ref, mask)); + GL_EXTCALL(glStencilOpSeparate(GL_BACK, stencilFail_back, depthFail_back, stencilPass_back)); checkGLcall("setting two sided stencil state"); } else if (gl_info->supported[EXT_STENCIL_TWO_SIDE]) @@ -875,22 +898,22 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ * to set it back */ renderstate_stencil_twosided(context, GL_BACK, - func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw); + func_back, ref, mask, stencilFail_back, depthFail_back, stencilPass_back); renderstate_stencil_twosided(context, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass); } else if (gl_info->supported[ATI_SEPARATE_STENCIL]) { - GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask)); + GL_EXTCALL(glStencilFuncSeparateATI(func, func_back, ref, mask)); checkGLcall("glStencilFuncSeparateATI(...)"); GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass)); checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)"); - GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw)); + GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_back, depthFail_back, stencilPass_back)); checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)"); } else { - ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n"); + FIXME("Separate (two sided) stencil not supported on this version of OpenGL. Caps weren't honored?\n"); } } else if(onesided_enable) @@ -920,11 +943,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -#else /* STAGING_CSMT */ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -#endif /* STAGING_CSMT */ const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); @@ -938,11 +957,7 @@ static void state_stencilwrite2s(struct wined3d_context *context, const struct w static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -#else /* STAGING_CSMT */ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -#endif /* STAGING_CSMT */ const struct wined3d_gl_info *gl_info = context->gl_info; gl_info->gl_ops.gl.p_glStencilMask(mask); @@ -1144,17 +1159,10 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st /* drop through */ case WINED3D_FOG_NONE: -#if defined(STAGING_CSMT) - /* Both are none? According to msdn the alpha channel of the specular - * color contains a fog factor. Set it in draw_strided_slow. - * Same happens with Vertexfog on transformed vertices - */ -#else /* STAGING_CSMT */ - /* Both are none? According to msdn the alpha channel of the specular - * color contains a fog factor. Set it in drawStridedSlow. - * Same happens with Vertexfog on transformed vertices - */ -#endif /* STAGING_CSMT */ + /* Both are none? According to msdn the alpha channel of + * the specular colour contains a fog factor. Set it in + * draw_primitive_immediate_mode(). Same happens with + * vertex fog on transformed vertices. */ new_source = FOGSOURCE_COORD; gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); @@ -1205,10 +1213,10 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - float col[4]; + struct wined3d_color color; - D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col); - gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, col); + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_FOGCOLOR]); + gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &color.r); checkGLcall("glFog GL_FOG_COLOR"); } @@ -1380,6 +1388,14 @@ static void state_linepattern(struct wined3d_context *context, const struct wine } } +static void state_linepattern_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + static unsigned int once; + + if (!once++) + FIXME("Setting line patterns is not supported in OpenGL core contexts.\n"); +} + static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -1597,7 +1613,9 @@ void state_pointsprite(struct wined3d_context *context, const struct wined3d_sta static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - if (state->render_states[WINED3D_RS_WRAP0] + static unsigned int once; + + if ((state->render_states[WINED3D_RS_WRAP0] || state->render_states[WINED3D_RS_WRAP1] || state->render_states[WINED3D_RS_WRAP2] || state->render_states[WINED3D_RS_WRAP3] @@ -1613,6 +1631,7 @@ static void state_wrap(struct wined3d_context *context, const struct wined3d_sta || state->render_states[WINED3D_RS_WRAP13] || state->render_states[WINED3D_RS_WRAP14] || state->render_states[WINED3D_RS_WRAP15]) + && !once++) FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n"); } @@ -1638,6 +1657,23 @@ static void state_msaa(struct wined3d_context *context, const struct wined3d_sta } } +static void state_line_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (state->render_states[WINED3D_RS_EDGEANTIALIAS] + || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE]) + { + gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH); + checkGLcall("glEnable(GL_LINE_SMOOTH)"); + } + else + { + gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH); + checkGLcall("glDisable(GL_LINE_SMOOTH)"); + } +} + static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -1676,11 +1712,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] || state->render_states[WINED3D_RS_DEPTHBIAS]) { -#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; -#else /* STAGING_CSMT */ const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; -#endif /* STAGING_CSMT */ float scale; union @@ -1695,7 +1727,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL); checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)"); - if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS) + if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS) { float bias = -(float)const_bias.d; gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias); @@ -3298,7 +3330,7 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d return; } - if (mapped_stage >= gl_info->limits.fragment_samplers) + if (mapped_stage >= min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_FRAGMENT_SAMPLERS)) { WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage); return; @@ -3464,27 +3496,25 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - if(!texture) return; + if (!texture) + return; + /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the - * scaling is reapplied or removed, the texture matrix has to be reapplied - * - * The mapped stage is already active because the sampler() function below, which is part of the - * misc pipeline + * scaling is reapplied or removed, the texture matrix has to be reapplied. */ if (sampler < MAX_TEXTURES) { - const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT); + const BOOL tex_is_pow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT); - if (texIsPow2 || (context->lastWasPow2Texture & (1u << sampler))) + if (tex_is_pow2 || (context->lastWasPow2Texture & (1u << sampler))) { - if (texIsPow2) + if (tex_is_pow2) context->lastWasPow2Texture |= 1u << sampler; else context->lastWasPow2Texture &= ~(1u << sampler); - transform_texture(context, state, - STATE_TEXTURESTAGE(context->tex_unit_map[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); + transform_texture(context, state, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); } } } @@ -3518,7 +3548,8 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]); desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]); desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]); - D3DCOLORTOGLFLOAT4(sampler_states[WINED3D_SAMP_BORDER_COLOR], desc->border_color); + wined3d_color_from_d3dcolor((struct wined3d_color *)desc->border_color, + sampler_states[WINED3D_SAMP_BORDER_COLOR]); if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC) FIXME("Unrecognized or unsupported WINED3D_SAMP_MAG_FILTER %#x.\n", sampler_states[WINED3D_SAMP_MAG_FILTER]); @@ -3535,6 +3566,7 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc desc->lod_bias = lod_bias.f; desc->min_lod = -1000.0f; desc->max_lod = 1000.0f; + desc->mip_base_level = sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL]; desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY]; if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC @@ -3571,84 +3603,50 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state TRACE("Sampler %u.\n", sampler_idx); - if (mapped_stage == WINED3D_UNMAPPED_STAGE) { TRACE("No sampler mapped to stage %u. Returning.\n", sampler_idx); return; } - if (mapped_stage >= gl_info->limits.combined_samplers) - { + if (mapped_stage >= gl_info->limits.graphics_samplers) return; - } context_active_texture(context, gl_info, mapped_stage); if (state->textures[sampler_idx]) { - struct wined3d_texture *texture = state->textures[sampler_idx]; BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE]; const DWORD *sampler_states = state->sampler_states[sampler_idx]; + struct wined3d_texture *texture = state->textures[sampler_idx]; + struct wined3d_device *device = context->device; struct wined3d_sampler_desc desc; - struct gl_texture *gl_tex; - unsigned int base_level; + struct wined3d_sampler *sampler; + struct wine_rb_entry *entry; wined3d_sampler_desc_from_sampler_states(&desc, context, sampler_states, texture); wined3d_texture_bind(texture, context, srgb); - if (!gl_info->supported[ARB_SAMPLER_OBJECTS]) + + if ((entry = wine_rb_get(&device->samplers, &desc))) { - wined3d_texture_apply_sampler_desc(texture, &desc, context); + sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry); } else { - struct wined3d_device *device = context->swapchain->device; - struct wined3d_sampler *sampler; - struct wine_rb_entry *entry; - - if ((entry = wine_rb_get(&device->samplers, &desc))) + if (FAILED(wined3d_sampler_create(device, &desc, NULL, &wined3d_null_parent_ops, &sampler))) { - sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry); + ERR("Failed to create sampler.\n"); + return; } - else + if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1) { - if (FAILED(wined3d_sampler_create(device, &desc, NULL, &sampler))) - { - ERR("Failed to create sampler.\n"); - sampler = NULL; - } - else - { - if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1) - ERR("Failed to insert sampler.\n"); - } - } - - if (sampler) - { - GL_EXTCALL(glBindSampler(mapped_stage, sampler->name)); - checkGLcall("glBindSampler"); + ERR("Failed to insert sampler.\n"); + wined3d_sampler_decref(sampler); + return; } } - if (texture->flags & WINED3D_TEXTURE_COND_NP2) - base_level = 0; - else if (desc.mip_filter == WINED3D_TEXF_NONE) - base_level = texture->lod; - else - base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL], - texture->lod), texture->level_count - 1); - - gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB); - if (base_level != gl_tex->base_level) - { - /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap - * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest - * mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL - * corresponds to GL_TEXTURE_BASE_LEVEL. */ - gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level); - gl_tex->base_level = base_level; - } + wined3d_sampler_bind(sampler, mapped_stage, texture, context); /* Trigger shader constant reloading (for NP2 texcoord fixup) */ if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) @@ -3657,6 +3655,11 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state else { context_bind_texture(context, GL_NONE, 0); + if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + { + GL_EXTCALL(glBindSampler(mapped_stage, 0)); + checkGLcall("glBindSampler"); + } } } @@ -3700,9 +3703,15 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; } -static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_compute_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_GEOMETRY; + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_COMPUTE; +} + +static void state_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + enum wined3d_shader_type shader_type = state_id - STATE_SHADER(0); + context->shader_update_mask |= 1u << shader_type; } static void shader_bumpenv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -3737,7 +3746,7 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat UINT index = state_id - STATE_CLIPPLANE(0); GLdouble plane[4]; - if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes) + if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.user_clip_distances) return; gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); @@ -3748,7 +3757,7 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); else /* With vertex shaders, clip planes are not transformed in Direct3D, - * while in OpenGL they are still transformed by the model view matix. */ + * while in OpenGL they are still transformed by the model view matrix. */ gl_info->gl_ops.gl.p_glLoadIdentity(); plane[0] = state->clip_planes[index].x; @@ -3818,8 +3827,8 @@ static void state_vertexblend_w(struct wined3d_context *context, const struct wi static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND]; - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; static unsigned int once; switch (val) @@ -3891,7 +3900,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d } /* Reset Clipping Planes */ - for (k = 0; k < gl_info->limits.clipplanes; ++k) + for (k = 0; k < gl_info->limits.user_clip_distances; ++k) { if (!isStateDirty(context, STATE_CLIPPLANE(k))) clipplane(context, state, STATE_CLIPPLANE(k)); @@ -3911,7 +3920,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); /* Avoid looping over a number of matrices if the app never used the functionality */ - if (context->swapchain->device->vertexBlendUsed) + if (context->device->vertexBlendUsed) { for (k = 1; k < gl_info->limits.blends; ++k) { @@ -3975,15 +3984,17 @@ static void unload_numbered_arrays(struct wined3d_context *context) static void load_numbered_arrays(struct wined3d_context *context, const struct wined3d_stream_info *stream_info, const struct wined3d_state *state) { + const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct wined3d_gl_info *gl_info = context->gl_info; GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - int i; + unsigned int i; /* Default to no instancing */ context->instance_count = 0; - for (i = 0; i < MAX_ATTRIBS; i++) + for (i = 0; i < MAX_ATTRIBS; ++i) { + const struct wined3d_stream_info_element *element = &stream_info->elements[i]; const struct wined3d_stream_state *stream; if (!(stream_info->use_map & (1u << i))) @@ -3997,16 +4008,16 @@ static void load_numbered_arrays(struct wined3d_context *context, continue; } - stream = &state->streams[stream_info->elements[i].stream_idx]; + stream = &state->streams[element->stream_idx]; if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count) context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1; if (gl_info->supported[ARB_INSTANCED_ARRAYS]) { - GL_EXTCALL(glVertexAttribDivisor(i, stream_info->elements[i].divisor)); + GL_EXTCALL(glVertexAttribDivisor(i, element->divisor)); } - else if (stream_info->elements[i].divisor) + else if (element->divisor) { /* Unload instanced arrays, they will be loaded using * immediate mode instead. */ @@ -4015,25 +4026,32 @@ static void load_numbered_arrays(struct wined3d_context *context, continue; } - TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object); + TRACE_(d3d_shader)("Loading array %u [VBO=%u].\n", i, element->data.buffer_object); - if (stream_info->elements[i].stride) + if (element->stride) { - if (curVBO != stream_info->elements[i].data.buffer_object) + if (curVBO != element->data.buffer_object) { - GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, stream_info->elements[i].data.buffer_object)); + GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object)); checkGLcall("glBindBuffer"); - curVBO = stream_info->elements[i].data.buffer_object; + curVBO = element->data.buffer_object; } /* Use the VBO to find out if a vertex buffer exists, not the vb * pointer. vb can point to a user pointer data blob. In that case * curVBO will be 0. If there is a vertex buffer but no vbo we * won't be load converted attributes anyway. */ - GL_EXTCALL(glVertexAttribPointer(i, stream_info->elements[i].format->gl_vtx_format, - stream_info->elements[i].format->gl_vtx_type, - stream_info->elements[i].format->gl_normalized, - stream_info->elements[i].stride, stream_info->elements[i].data.addr - + state->load_base_vertex_index * stream_info->elements[i].stride)); + if (vs && vs->reg_maps.shader_version.major >= 4 + && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER)) + { + GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, + element->stride, element->data.addr + state->load_base_vertex_index * element->stride)); + } + else + { + GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type, + element->format->gl_normalized, element->stride, + element->data.addr + state->load_base_vertex_index * element->stride)); + } if (!(context->numbered_array_mask & (1u << i))) { @@ -4047,15 +4065,14 @@ static void load_numbered_arrays(struct wined3d_context *context, * glVertexAttribPointer doesn't do that. Instead disable the * pointer and set up the attribute statically. But we have to * figure out the system memory address. */ - const BYTE *ptr = stream_info->elements[i].data.addr; - if (stream_info->elements[i].data.buffer_object) - { - ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, context); - } + const BYTE *ptr = element->data.addr; + if (element->data.buffer_object) + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); - if (context->numbered_array_mask & (1u << i)) unload_numbered_array(context, i); + if (context->numbered_array_mask & (1u << i)) + unload_numbered_array(context, i); - switch (stream_info->elements[i].format->id) + switch (element->format->id) { case WINED3DFMT_R32_FLOAT: GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr)); @@ -4114,12 +4131,12 @@ static void load_numbered_arrays(struct wined3d_context *context, GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr)); break; - case WINED3DFMT_R10G10B10A2_UINT: - FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n"); + case WINED3DFMT_R10G10B10X2_UINT: + FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n"); /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */ break; - case WINED3DFMT_R10G10B10A2_SNORM: - FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n"); + case WINED3DFMT_R10G10B10X2_SNORM: + FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n"); /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */ break; @@ -4153,7 +4170,7 @@ static void load_numbered_arrays(struct wined3d_context *context, break; default: - ERR("Unexpected declaration in stride 0 attributes\n"); + ERR("Unexpected declaration in stride 0 attributes.\n"); break; } @@ -4216,17 +4233,13 @@ static void load_vertex_data(struct wined3d_context *context, warned = TRUE; } } - } else { -#if defined(STAGING_CSMT) - /* TODO: support blends in draw_strided_slow - * No need to write a FIXME here, this is done after the general vertex decl decoding - */ -#else /* STAGING_CSMT */ - /* TODO: support blends in drawStridedSlow - * No need to write a FIXME here, this is done after the general vertex decl decoding - */ -#endif /* STAGING_CSMT */ - WARN("unsupported blending in openGl\n"); + } + else + { + /* TODO: Support vertex blending in immediate mode draws. No need + * to write a FIXME here, this is done after the general vertex + * declaration decoding. */ + WARN("Vertex blending not supported.\n"); } } else @@ -4459,6 +4472,11 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine context->last_was_rhw = transformed; + if (context->stream_info.swizzle_map != context->last_swizzle_map) + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; + + context->last_swizzle_map = context->stream_info.swizzle_map; + /* Don't have to apply the matrices when vertex shaders are used. When * vshaders are turned off this function will be called again anyway to * make sure they're properly set. */ @@ -4499,7 +4517,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)); } - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { clipplane(context, state, STATE_CLIPPLANE(i)); } @@ -4516,7 +4534,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine /* Disable all clip planes to get defined results on all drivers. See comment in the * state_clipping state handler */ - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i); checkGLcall("glDisable(GL_CLIP_PLANE0 + i)"); @@ -4548,7 +4566,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine * (Note: ARB shaders can read the clip planes for clipping emulation even if * device->vs_clipping is false. */ - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { clipplane(context, state, STATE_CLIPPLANE(i)); } @@ -4579,36 +4597,95 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { -#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; -#else /* STAGING_CSMT */ + const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; -#endif /* STAGING_CSMT */ const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_viewport vp = state->viewport; + unsigned int width, height; + float y; - if (vp.width > target->width) - vp.width = target->width; - if (vp.height > target->height) - vp.height = target->height; + if (target) + { + if (vp.width > target->width) + vp.width = target->width; + if (vp.height > target->height) + vp.height = target->height; + + wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); + } + else if (depth_stencil) + { + width = depth_stencil->width; + height = depth_stencil->height; + } + else + { + FIXME("No attachments draw calls not supported.\n"); + return; + } gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); checkGLcall("glDepthRange"); /* Note: GL requires lower left, DirectX supplies upper left. This is * reversed when using offscreen rendering. */ - if (context->render_offscreen) + y = context->render_offscreen ? vp.y : height - (vp.y + vp.height); + + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + GL_EXTCALL(glViewportIndexedf(0, vp.x, y, vp.width, vp.height)); + else + gl_info->gl_ops.gl.p_glViewport(vp.x, y, vp.width, vp.height); + checkGLcall("glViewport"); +} + +static void viewport_miscpart_cc(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; + const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + /* See get_projection_matrix() in utils.c for a discussion about those + * values. */ + float pixel_center_offset = context->d3d_info->wined3d_creation_flags + & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_viewport vp = state->viewport; + unsigned int width, height; + + if (target) { - gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height); + if (vp.width > target->width) + vp.width = target->width; + if (vp.height > target->height) + vp.height = target->height; + + wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); + } + else if (depth_stencil) + { + width = depth_stencil->width; + height = depth_stencil->height; } else { - UINT width, height; - - surface_get_drawable_size(wined3d_rendertarget_view_get_surface(target), context, &width, &height); - gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)), - vp.width, vp.height); + FIXME("No attachments draw calls not supported.\n"); + return; } - checkGLcall("glViewport"); + + gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); + checkGLcall("glDepthRange"); + + if (context->render_offscreen) + { + GL_EXTCALL(glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE)); + GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset, vp.y + pixel_center_offset, + vp.width, vp.height)); + } + else + { + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE)); + GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset, + (height - (vp.y + vp.height)) + pixel_center_offset, vp.width, vp.height)); + } + checkGLcall("setting clip space and viewport"); } static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4619,7 +4696,7 @@ static void viewport_vertexpart(struct wined3d_context *context, const struct wi && state->render_states[WINED3D_RS_POINTSCALEENABLE]) state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)); /* Update the position fixup. */ - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP; + context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; } static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4761,15 +4838,11 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st } else { -#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; -#else /* STAGING_CSMT */ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; -#endif /* STAGING_CSMT */ UINT height; UINT width; - surface_get_drawable_size(wined3d_rendertarget_view_get_surface(target), context, &width, &height); + wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height); gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top); } checkGLcall("glScissor"); @@ -4794,17 +4867,25 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum mode; + mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; if (context->render_offscreen) - { - gl_info->gl_ops.gl.p_glFrontFace(GL_CCW); - checkGLcall("glFrontFace(GL_CCW)"); - } - else - { - gl_info->gl_ops.gl.p_glFrontFace(GL_CW); - checkGLcall("glFrontFace(GL_CW)"); - } + mode = (mode == GL_CW) ? GL_CCW : GL_CW; + + gl_info->gl_ops.gl.p_glFrontFace(mode); + checkGLcall("glFrontFace"); +} + +static void frontface_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum mode; + + mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; + + gl_info->gl_ops.gl.p_glFrontFace(mode); + checkGLcall("glFrontFace"); } static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4833,57 +4914,33 @@ void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); -#if defined(STAGING_CSMT) - if (needs_srgb_write(context, state, &state->fb)) -#else /* STAGING_CSMT */ if (needs_srgb_write(context, state, state->fb)) -#endif /* STAGING_CSMT */ gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); else gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); } -static void state_cb(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, - enum wined3d_shader_type type, unsigned int base, unsigned int count) +static void state_cb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + const struct wined3d_gl_info *gl_info = context->gl_info; + enum wined3d_shader_type shader_type; struct wined3d_buffer *buffer; - unsigned int i; + unsigned int i, base, count; + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + + if (STATE_IS_GRAPHICS_CONSTANT_BUFFER(state_id)) + shader_type = state_id - STATE_GRAPHICS_CONSTANT_BUFFER(0); + else + shader_type = WINED3D_SHADER_TYPE_COMPUTE; + + wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, shader_type, &base, &count); for (i = 0; i < count; ++i) { - buffer = state->cb[type][i]; + buffer = state->cb[shader_type][i]; GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer ? buffer->buffer_object : 0)); } - checkGLcall("glBindBufferBase"); -} - -static void state_cb_vs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - const struct wined3d_gl_limits *limits = &context->gl_info->limits; - - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - - state_cb(context->gl_info, state, WINED3D_SHADER_TYPE_VERTEX, 0, limits->vertex_uniform_blocks); -} - -static void state_cb_gs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - const struct wined3d_gl_limits *limits = &context->gl_info->limits; - - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - - state_cb(context->gl_info, state, WINED3D_SHADER_TYPE_GEOMETRY, - limits->vertex_uniform_blocks, limits->geometry_uniform_blocks); -} - -static void state_cb_ps(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - const struct wined3d_gl_limits *limits = &context->gl_info->limits; - - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); - - state_cb(context->gl_info, state, WINED3D_SHADER_TYPE_PIXEL, - limits->vertex_uniform_blocks + limits->geometry_uniform_blocks, limits->fragment_uniform_blocks); + checkGLcall("bind constant buffers"); } static void state_cb_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4901,20 +4958,95 @@ static void state_shader_resource_binding(struct wined3d_context *context, context->update_shader_resource_bindings = 1; } +static void state_cs_resource_binding(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + context->update_compute_shader_resource_bindings = 1; +} + +static void state_uav_binding(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + context->update_unordered_access_view_bindings = 1; +} + +static void state_cs_uav_binding(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + context->update_compute_unordered_access_view_bindings = 1; +} + +static void state_uav_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + WARN("ARB_image_load_store is not supported by OpenGL implementation.\n"); +} + +static void state_so(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_buffer *buffer; + unsigned int offset, size, i; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + + context_end_transform_feedback(context); + + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) + { + if (!(buffer = state->stream_output[i].buffer)) + { + GL_EXTCALL(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0)); + continue; + } + + offset = state->stream_output[i].offset; + if (offset == ~0u) + { + FIXME("Appending to stream output buffers not implemented.\n"); + offset = 0; + } + size = buffer->resource.size - offset; + GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, + buffer->buffer_object, offset, size)); + } + checkGLcall("bind transform feedback buffers"); +} + +static void state_so_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + WARN("Transform feedback not supported.\n"); +} + const struct StateEntryTemplate misc_state_template[] = { - { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb_vs, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb_warn, }, WINED3D_GL_EXT_NONE }, - { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),state_cb_gs, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), state_cb_warn, }, WINED3D_GL_EXT_NONE }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), state_cb_warn, }, WINED3D_GL_EXT_NONE }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),{ STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY),state_cb_warn, }, WINED3D_GL_EXT_NONE }, - { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_cb_ps, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_cb_warn, }, WINED3D_GL_EXT_NONE }, - { STATE_SHADER_RESOURCE_BINDING, { STATE_SHADER_RESOURCE_BINDING, state_shader_resource_binding}, WINED3D_GL_EXT_NONE }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, + { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), state_cb_warn, }, WINED3D_GL_EXT_NONE }, + { STATE_GRAPHICS_SHADER_RESOURCE_BINDING, { STATE_GRAPHICS_SHADER_RESOURCE_BINDING, state_shader_resource_binding}, WINED3D_GL_EXT_NONE }, + { STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, { STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, state_uav_binding }, ARB_SHADER_IMAGE_LOAD_STORE }, + { STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, { STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, state_uav_warn }, WINED3D_GL_EXT_NONE }, + { STATE_COMPUTE_SHADER_RESOURCE_BINDING, { STATE_COMPUTE_SHADER_RESOURCE_BINDING, state_cs_resource_binding}, WINED3D_GL_EXT_NONE }, + { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_cs_uav_binding}, ARB_SHADER_IMAGE_LOAD_STORE }, + { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_uav_warn }, WINED3D_GL_EXT_NONE }, + { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so, }, WINED3D_GL_VERSION_3_2 }, + { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so_warn, }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), state_line_antialias}, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), state_line_antialias}, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -4922,8 +5054,10 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, + { STATE_FRONTFACE, { STATE_FRONTFACE, frontface_cc }, ARB_CLIP_CONTROL }, { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, + { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, state_nop }, ARB_CLIP_CONTROL }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE }, @@ -4979,6 +5113,7 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart_cc}, ARB_CLIP_CONTROL }, { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, @@ -4988,11 +5123,12 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_LEGACY_CONTEXT }, + { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwriteenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE }, @@ -5015,10 +5151,10 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, @@ -5095,7 +5231,10 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE }, { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE }, { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), context_state_drawbuf},WINED3D_GL_EXT_NONE }, - { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), state_geometry_shader}, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_HULL), { STATE_SHADER(WINED3D_SHADER_TYPE_HULL), state_shader }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN), { STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN), state_shader }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), { STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), state_shader }, WINED3D_GL_EXT_NONE }, + { STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE), { STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE), state_compute_shader}, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; @@ -5632,7 +5771,7 @@ static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3 | WINED3DVTXPCAPS_TEXGEN | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP; caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */ - caps->max_user_clip_planes = gl_info->limits.clipplanes; + caps->max_user_clip_planes = gl_info->limits.user_clip_distances; caps->raster_caps = 0; if (gl_info->supported[NV_FOG_DISTANCE]) caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE; @@ -5805,15 +5944,15 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs) static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id); + context->device->multistate_funcs[state_id][0](context, state, state_id); + context->device->multistate_funcs[state_id][1](context, state, state_id); } static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id); + context->device->multistate_funcs[state_id][0](context, state, state_id); + context->device->multistate_funcs[state_id][1](context, state, state_id); + context->device->multistate_funcs[state_id][2](context, state, state_id); } static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info, @@ -5875,12 +6014,21 @@ static void validate_state_table(struct StateEntry *state_table) STATE_STREAMSRC, STATE_INDEXBUFFER, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), + STATE_SHADER(WINED3D_SHADER_TYPE_HULL), + STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN), STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), + STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE), STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY), STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), - STATE_SHADER_RESOURCE_BINDING, + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), + STATE_COMPUTE_SHADER_RESOURCE_BINDING, + STATE_GRAPHICS_SHADER_RESOURCE_BINDING, + STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, + STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, STATE_VIEWPORT, STATE_LIGHT_TYPE, STATE_SCISSORRECT, @@ -6001,12 +6149,8 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ break; case 1: StateTable[cur[i].state].apply = multistate_apply_2; - dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(), - 0, - sizeof(**dev_multistate_funcs) * 2); - if (!dev_multistate_funcs[cur[i].state]) { + if (!(dev_multistate_funcs[cur[i].state] = wined3d_calloc(2, sizeof(**dev_multistate_funcs)))) goto out_of_mem; - } dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0]; dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1]; diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 4938bed14a1..27d14c94919 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -36,9 +36,9 @@ static const DWORD pixel_states_render[] = WINED3D_RS_BLENDFACTOR, WINED3D_RS_BLENDOP, WINED3D_RS_BLENDOPALPHA, - WINED3D_RS_CCW_STENCILFAIL, - WINED3D_RS_CCW_STENCILPASS, - WINED3D_RS_CCW_STENCILZFAIL, + WINED3D_RS_BACK_STENCILFAIL, + WINED3D_RS_BACK_STENCILPASS, + WINED3D_RS_BACK_STENCILZFAIL, WINED3D_RS_COLORWRITEENABLE, WINED3D_RS_COLORWRITEENABLE1, WINED3D_RS_COLORWRITEENABLE2, @@ -187,40 +187,6 @@ static const DWORD vertex_states_sampler[] = WINED3D_SAMP_DMAP_OFFSET, }; -/* Allocates the correct amount of space for pixel and vertex shader constants, - * along with their set/changed flags on the given stateblock object - */ -static HRESULT stateblock_allocate_shader_constants(struct wined3d_stateblock *object) -{ - const struct wined3d_d3d_info *d3d_info = &object->device->adapter->d3d_info; - - object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(BOOL) * d3d_info->limits.ps_uniform_count); - if (!object->changed.pixelShaderConstantsF) goto fail; - - object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(BOOL) * d3d_info->limits.vs_uniform_count); - if (!object->changed.vertexShaderConstantsF) goto fail; - - object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, - sizeof(DWORD) * d3d_info->limits.vs_uniform_count); - if (!object->contained_vs_consts_f) goto fail; - - object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, - sizeof(DWORD) * d3d_info->limits.ps_uniform_count); - if (!object->contained_ps_consts_f) goto fail; - - return WINED3D_OK; - -fail: - ERR("Failed to allocate memory\n"); - HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF); - HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF); - HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f); - HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f); - return E_OUTOFMEMORY; -} - static inline void stateblock_set_bits(DWORD *map, UINT map_size) { DWORD mask = (1u << (map_size & 0x1f)) - 1; @@ -234,7 +200,6 @@ static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, unsigned int i; /* Single values */ - states->primitive_type = 1; states->indices = 1; states->material = 1; states->viewport = 1; @@ -258,8 +223,8 @@ static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, states->vertexShaderConstantsI = 0xffff; /* Dynamically sized arrays */ - memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * ps_consts); - memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * vs_consts); + memset(states->ps_consts_f, TRUE, sizeof(BOOL) * ps_consts); + memset(states->vs_consts_f, TRUE, sizeof(BOOL) * vs_consts); } static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states, const DWORD num_constants) @@ -285,7 +250,7 @@ static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states states->pixelShaderConstantsB = 0xffff; states->pixelShaderConstantsI = 0xffff; - memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * num_constants); + memset(states->ps_consts_f, TRUE, sizeof(BOOL) * num_constants); } static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *states, const DWORD num_constants) @@ -312,7 +277,7 @@ static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *state states->vertexShaderConstantsB = 0xffff; states->vertexShaderConstantsI = 0xffff; - memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * num_constants); + memset(states->vs_consts_f, TRUE, sizeof(BOOL) * num_constants); } void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) @@ -346,14 +311,14 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i) { - if (stateblock->changed.vertexShaderConstantsF[i]) + if (stateblock->changed.vs_consts_f[i]) { stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i; ++stateblock->num_contained_vs_consts_f; } } - for (i = 0; i < MAX_CONST_I; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if (stateblock->changed.vertexShaderConstantsI & (1u << i)) { @@ -362,7 +327,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i < MAX_CONST_B; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { if (stateblock->changed.vertexShaderConstantsB & (1u << i)) { @@ -373,14 +338,14 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) for (i = 0; i < d3d_info->limits.ps_uniform_count; ++i) { - if (stateblock->changed.pixelShaderConstantsF[i]) + if (stateblock->changed.ps_consts_f[i]) { stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i; ++stateblock->num_contained_ps_consts_f; } } - for (i = 0; i < MAX_CONST_I; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { if (stateblock->changed.pixelShaderConstantsI & (1u << i)) { @@ -389,7 +354,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } } - for (i = 0; i < MAX_CONST_B; ++i) + for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) { if (stateblock->changed.pixelShaderConstantsB & (1u << i)) { @@ -456,15 +421,13 @@ ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock) void state_unbind_resources(struct wined3d_state *state) { + struct wined3d_unordered_access_view *uav; struct wined3d_shader_resource_view *srv; struct wined3d_vertex_declaration *decl; struct wined3d_sampler *sampler; struct wined3d_texture *texture; struct wined3d_buffer *buffer; struct wined3d_shader *shader; -#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *view; -#endif /* STAGING_CSMT */ unsigned int i, j; if ((decl = state->vertex_declaration)) @@ -482,7 +445,7 @@ void state_unbind_resources(struct wined3d_state *state) } } - for (i = 0; i < MAX_STREAM_OUT; ++i) + for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) { if ((buffer = state->stream_output[i].buffer)) { @@ -541,33 +504,18 @@ void state_unbind_resources(struct wined3d_state *state) } } } -#if defined(STAGING_CSMT) - if (state->fb.depth_stencil) + for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i) { - view = state->fb.depth_stencil; - - TRACE("Releasing depth/stencil buffer %p.\n", view); - - state->fb.depth_stencil = NULL; - wined3d_rendertarget_view_decref(view); - } - - if (state->fb.render_targets) - { - for (i = 0; i < state->fb.rt_size; i++) + for (j = 0; j < MAX_UNORDERED_ACCESS_VIEWS; ++j) { - view = state->fb.render_targets[i]; - TRACE("Setting rendertarget %u to NULL\n", i); - state->fb.render_targets[i] = NULL; - if (view) + if ((uav = state->unordered_access_view[i][j])) { - TRACE("Releasing the rendertarget view at %p\n", view); - wined3d_rendertarget_view_decref(view); + state->unordered_access_view[i][j] = NULL; + wined3d_unordered_access_view_decref(uav); } } } -#endif /* STAGING_CSMT */ } void state_cleanup(struct wined3d_state *state) @@ -592,12 +540,6 @@ void state_cleanup(struct wined3d_state *state) HeapFree(GetProcessHeap(), 0, light); } } - - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - HeapFree(GetProcessHeap(), 0, state->ps_consts_f); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, state->fb.render_targets); -#endif /* STAGING_CSMT */ } ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) @@ -609,17 +551,72 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) if (!refcount) { state_cleanup(&stateblock->state); - - HeapFree(GetProcessHeap(), 0, stateblock->changed.vertexShaderConstantsF); - HeapFree(GetProcessHeap(), 0, stateblock->changed.pixelShaderConstantsF); - HeapFree(GetProcessHeap(), 0, stateblock->contained_vs_consts_f); - HeapFree(GetProcessHeap(), 0, stateblock->contained_ps_consts_f); HeapFree(GetProcessHeap(), 0, stateblock); } return refcount; } +struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, unsigned int idx) +{ + struct wined3d_light_info *light_info; + unsigned int hash_idx; + + hash_idx = LIGHTMAP_HASHFUNC(idx); + LIST_FOR_EACH_ENTRY(light_info, &state->light_map[hash_idx], struct wined3d_light_info, entry) + { + if (light_info->OriginalIndex == idx) + return light_info; + } + + return NULL; +} + +void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, + struct wined3d_light_info *light_info, BOOL enable) +{ + unsigned int light_count, i; + + if (!(light_info->enabled = enable)) + { + if (light_info->glIndex == -1) + { + TRACE("Light already disabled, nothing to do.\n"); + return; + } + + state->lights[light_info->glIndex] = NULL; + light_info->glIndex = -1; + return; + } + + if (light_info->glIndex != -1) + { + TRACE("Light already enabled, nothing to do.\n"); + return; + } + + /* Find a free light. */ + light_count = d3d_info->limits.active_light_count; + for (i = 0; i < light_count; ++i) + { + if (state->lights[i]) + continue; + + state->lights[i] = light_info; + light_info->glIndex = i; + return; + } + + /* Our tests show that Windows returns D3D_OK in this situation, even with + * D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE devices. + * This is consistent among ddraw, d3d8 and d3d9. GetLightEnable returns + * TRUE * as well for those lights. + * + * TODO: Test how this affects rendering. */ + WARN("Too many concurrently active lights.\n"); +} + static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state) { UINT i; @@ -706,16 +703,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_f[i]; - TRACE("Setting vs_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx, - src_state->vs_consts_f[idx * 4 + 0], - src_state->vs_consts_f[idx * 4 + 1], - src_state->vs_consts_f[idx * 4 + 2], - src_state->vs_consts_f[idx * 4 + 3]); + TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->vs_consts_f[idx])); - stateblock->state.vs_consts_f[idx * 4 + 0] = src_state->vs_consts_f[idx * 4 + 0]; - stateblock->state.vs_consts_f[idx * 4 + 1] = src_state->vs_consts_f[idx * 4 + 1]; - stateblock->state.vs_consts_f[idx * 4 + 2] = src_state->vs_consts_f[idx * 4 + 2]; - stateblock->state.vs_consts_f[idx * 4 + 3] = src_state->vs_consts_f[idx * 4 + 3]; + stateblock->state.vs_consts_f[idx] = src_state->vs_consts_f[idx]; } /* Vertex shader integer constants. */ @@ -723,16 +713,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_i[i]; - TRACE("Setting vs_consts[%u] to {%d, %d, %d, %d}.\n", idx, - src_state->vs_consts_i[idx * 4 + 0], - src_state->vs_consts_i[idx * 4 + 1], - src_state->vs_consts_i[idx * 4 + 2], - src_state->vs_consts_i[idx * 4 + 3]); + TRACE("Setting vs_consts[%u] to %s.\n", idx, debug_ivec4(&src_state->vs_consts_i[idx])); - stateblock->state.vs_consts_i[idx * 4 + 0] = src_state->vs_consts_i[idx * 4 + 0]; - stateblock->state.vs_consts_i[idx * 4 + 1] = src_state->vs_consts_i[idx * 4 + 1]; - stateblock->state.vs_consts_i[idx * 4 + 2] = src_state->vs_consts_i[idx * 4 + 2]; - stateblock->state.vs_consts_i[idx * 4 + 3] = src_state->vs_consts_i[idx * 4 + 3]; + stateblock->state.vs_consts_i[idx] = src_state->vs_consts_i[idx]; } /* Vertex shader boolean constants. */ @@ -751,32 +734,19 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_ps_consts_f[i]; - TRACE("Setting ps_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx, - src_state->ps_consts_f[idx * 4 + 0], - src_state->ps_consts_f[idx * 4 + 1], - src_state->ps_consts_f[idx * 4 + 2], - src_state->ps_consts_f[idx * 4 + 3]); + TRACE("Setting ps_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->ps_consts_f[idx])); - stateblock->state.ps_consts_f[idx * 4 + 0] = src_state->ps_consts_f[idx * 4 + 0]; - stateblock->state.ps_consts_f[idx * 4 + 1] = src_state->ps_consts_f[idx * 4 + 1]; - stateblock->state.ps_consts_f[idx * 4 + 2] = src_state->ps_consts_f[idx * 4 + 2]; - stateblock->state.ps_consts_f[idx * 4 + 3] = src_state->ps_consts_f[idx * 4 + 3]; + stateblock->state.ps_consts_f[idx] = src_state->ps_consts_f[idx]; } /* Pixel shader integer constants. */ for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i) { unsigned int idx = stateblock->contained_ps_consts_i[i]; - TRACE("Setting ps_consts_i[%u] to {%d, %d, %d, %d}.\n", idx, - src_state->ps_consts_i[idx * 4 + 0], - src_state->ps_consts_i[idx * 4 + 1], - src_state->ps_consts_i[idx * 4 + 2], - src_state->ps_consts_i[idx * 4 + 3]); - stateblock->state.ps_consts_i[idx * 4 + 0] = src_state->ps_consts_i[idx * 4 + 0]; - stateblock->state.ps_consts_i[idx * 4 + 1] = src_state->ps_consts_i[idx * 4 + 1]; - stateblock->state.ps_consts_i[idx * 4 + 2] = src_state->ps_consts_i[idx * 4 + 2]; - stateblock->state.ps_consts_i[idx * 4 + 3] = src_state->ps_consts_i[idx * 4 + 3]; + TRACE("Setting ps_consts_i[%u] to %s.\n", idx, debug_ivec4(&src_state->ps_consts_i[idx])); + + stateblock->state.ps_consts_i[idx] = src_state->ps_consts_i[idx]; } /* Pixel shader boolean constants. */ @@ -799,13 +769,11 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->state.transforms[transform] = src_state->transforms[transform]; } - if (stateblock->changed.primitive_type) - stateblock->state.gl_primitive_type = src_state->gl_primitive_type; - if (stateblock->changed.indices && ((stateblock->state.index_buffer != src_state->index_buffer) || (stateblock->state.base_vertex_index != src_state->base_vertex_index) - || (stateblock->state.index_format != src_state->index_format))) + || (stateblock->state.index_format != src_state->index_format) + || (stateblock->state.index_offset != src_state->index_offset))) { TRACE("Updating index buffer to %p, base vertex index to %d.\n", src_state->index_buffer, src_state->base_vertex_index); @@ -817,6 +785,7 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->state.index_buffer = src_state->index_buffer; stateblock->state.base_vertex_index = src_state->base_vertex_index; stateblock->state.index_format = src_state->index_format; + stateblock->state.index_offset = src_state->index_offset; } if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration != src_state->vertex_declaration) @@ -1001,17 +970,17 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i) { wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i], - stateblock->state.vs_consts_f + stateblock->contained_vs_consts_f[i] * 4, 1); + 1, &stateblock->state.vs_consts_f[stateblock->contained_vs_consts_f[i]]); } for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i) { wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i], - stateblock->state.vs_consts_i + stateblock->contained_vs_consts_i[i] * 4, 1); + 1, &stateblock->state.vs_consts_i[stateblock->contained_vs_consts_i[i]]); } for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i) { wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i], - stateblock->state.vs_consts_b + stateblock->contained_vs_consts_b[i], 1); + 1, &stateblock->state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); } apply_lights(device, &stateblock->state); @@ -1023,17 +992,17 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i) { wined3d_device_set_ps_consts_f(device, stateblock->contained_ps_consts_f[i], - stateblock->state.ps_consts_f + stateblock->contained_ps_consts_f[i] * 4, 1); + 1, &stateblock->state.ps_consts_f[stateblock->contained_ps_consts_f[i]]); } for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i) { wined3d_device_set_ps_consts_i(device, stateblock->contained_ps_consts_i[i], - stateblock->state.ps_consts_i + stateblock->contained_ps_consts_i[i] * 4, 1); + 1, &stateblock->state.ps_consts_i[stateblock->contained_ps_consts_i[i]]); } for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i) { wined3d_device_set_ps_consts_b(device, stateblock->contained_ps_consts_b[i], - stateblock->state.ps_consts_b + stateblock->contained_ps_consts_b[i], 1); + 1, &stateblock->state.ps_consts_b[stateblock->contained_ps_consts_b[i]]); } /* Render states. */ @@ -1070,27 +1039,10 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) &stateblock->state.transforms[stateblock->contained_transform_states[i]]); } - if (stateblock->changed.primitive_type) - { - GLenum gl_primitive_type, prev; - - if (device->recording) - device->recording->changed.primitive_type = TRUE; - gl_primitive_type = stateblock->state.gl_primitive_type; - prev = device->update_state->gl_primitive_type; - device->update_state->gl_primitive_type = gl_primitive_type; -#if defined(STAGING_CSMT) - if (gl_primitive_type != prev) - wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); -#else /* STAGING_CSMT */ - if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) - device_invalidate_state(device, STATE_POINT_ENABLE); -#endif /* STAGING_CSMT */ - } - if (stateblock->changed.indices) { - wined3d_device_set_index_buffer(device, stateblock->state.index_buffer, stateblock->state.index_format); + wined3d_device_set_index_buffer(device, stateblock->state.index_buffer, + stateblock->state.index_format, stateblock->state.index_offset); wined3d_device_set_base_vertex_index(device, stateblock->state.base_vertex_index); } @@ -1163,6 +1115,7 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d get_identity_matrix(&identity); state->gl_primitive_type = ~0u; + state->gl_patch_vertices = 0; /* Set some of the defaults for lights, transforms etc */ state->transforms[WINED3D_TS_PROJECTION] = identity; @@ -1185,7 +1138,7 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d state->render_states[WINED3D_RS_LASTPIXEL] = TRUE; state->render_states[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE; state->render_states[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO; - state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_CCW; + state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_BACK; state->render_states[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL; state->render_states[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS; state->render_states[WINED3D_RS_ALPHAREF] = 0; @@ -1278,10 +1231,10 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d state->render_states[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d; state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE; state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE; - state->render_states[WINED3D_RS_CCW_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_CCW_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_CCW_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; - state->render_states[WINED3D_RS_CCW_STENCILFUNC] = WINED3D_CMP_ALWAYS; + state->render_states[WINED3D_RS_BACK_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP; + state->render_states[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP; + state->render_states[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP; + state->render_states[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS; state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f; state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f; state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f; @@ -1343,29 +1296,10 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; /* TODO: Vertex offset in the presampled displacement map. */ state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; -#if defined(STAGING_CSMT) - state->textures[i] = NULL; - } - - state->index_buffer = NULL; - for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) - memset(&state->streams[i], 0, sizeof(state->streams[i])); - - state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; - state->shader[WINED3D_SHADER_TYPE_PIXEL] = NULL; -} - -HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, DWORD flags) -{ - unsigned int i; - - state->flags = flags; -#else /* STAGING_CSMT */ } } -HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, +void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, DWORD flags) { @@ -1373,68 +1307,24 @@ HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, state->flags = flags; state->fb = fb; -#endif /* STAGING_CSMT */ for (i = 0; i < LIGHTMAP_SIZE; i++) { list_init(&state->light_map[i]); } - if (!(state->vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - 4 * sizeof(float) * d3d_info->limits.vs_uniform_count))) - return E_OUTOFMEMORY; - - if (!(state->ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - 4 * sizeof(float) * d3d_info->limits.ps_uniform_count))) - { - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - return E_OUTOFMEMORY; - } - -#if defined(STAGING_CSMT) - if (!(state->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*state->fb.render_targets) * gl_info->limits.buffers))) - { - HeapFree(GetProcessHeap(), 0, state->ps_consts_f); - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - return E_OUTOFMEMORY; - } - state->fb.rt_size = gl_info->limits.buffers; - -#endif /* STAGING_CSMT */ if (flags & WINED3D_STATE_INIT_DEFAULT) state_init_default(state, gl_info); - - return WINED3D_OK; } static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, struct wined3d_device *device, enum wined3d_stateblock_type type) { - HRESULT hr; -#if defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; stateblock->ref = 1; stateblock->device = device; - - if (FAILED(hr = state_init(&stateblock->state, gl_info, d3d_info, 0))) -#else /* STAGING_CSMT */ - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - - stateblock->ref = 1; - stateblock->device = device; - - if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) -#endif /* STAGING_CSMT */ - return hr; - - if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) - { - state_cleanup(&stateblock->state); - return hr; - } + state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0); if (type == WINED3D_SBT_RECORDED) return WINED3D_OK; diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index a7a0a6635c3..91718e579b6 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -28,172 +28,18 @@ #include "wined3d_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); +WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); -WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ - -#if defined(STAGING_CSMT) - -static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter); - -void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) -{ - if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) -#else /* STAGING_CSMT */ -static const DWORD surface_simple_locations = - WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY - | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; - -static void surface_cleanup(struct wined3d_surface *surface) -{ - struct wined3d_surface *overlay, *cur; - - TRACE("surface %p.\n", surface); - - if (surface->pbo || surface->rb_multisample - || surface->rb_resolved || !list_empty(&surface->renderbuffers)) -#endif /* STAGING_CSMT */ - { - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - context = context_acquire(surface->resource.device, NULL); - gl_info = context->gl_info; - -#if !defined(STAGING_CSMT) - if (surface->pbo) - { - TRACE("Deleting PBO %u.\n", surface->pbo); - GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); - } - -#endif /* STAGING_CSMT */ - if (surface->rb_multisample) - { - TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample); - } - - if (surface->rb_resolved) - { - TRACE("Deleting resolved renderbuffer %u.\n", surface->rb_resolved); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved); - } - - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - TRACE("Deleting renderbuffer %u.\n", entry->id); - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - HeapFree(GetProcessHeap(), 0, entry); - } - - context_release(context); - } - - if (surface->flags & SFLAG_DIBSECTION) - { - DeleteDC(surface->hDC); - DeleteObject(surface->dib.DIBsection); -#if defined(STAGING_CSMT) - surface->resource.bitmap_data = NULL; - } - - TRACE("Destroyed surface %p.\n", surface); - HeapFree(GetProcessHeap(), 0, surface); -} - -static void surface_cleanup(struct wined3d_surface *surface) -{ - struct wined3d_surface *overlay, *cur; - struct wined3d_cs *cs = surface->resource.device->cs; - BOOL user_mem = surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY; - - TRACE("surface %p.\n", surface); -#else /* STAGING_CSMT */ - surface->dib.bitmap_data = NULL; - } -#endif /* STAGING_CSMT */ - - if (surface->overlay_dest) - list_remove(&surface->overlay_entry); - - LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &surface->overlays, struct wined3d_surface, overlay_entry) - { - list_remove(&overlay->overlay_entry); - overlay->overlay_dest = NULL; - } - - resource_cleanup(&surface->resource); -#if defined(STAGING_CSMT) - wined3d_cs_emit_surface_cleanup(cs, surface); - - /* Wait for the CS to finish operations on this surface when user memory was in use. - * The application is allowed to free the memory after texture / surface destruction - * returns. */ - if (user_mem) - wined3d_resource_wait_fence(&surface->container->resource); -} - -void wined3d_surface_destroy(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); - surface_cleanup(surface); -#else /* STAGING_CSMT */ -} - -void wined3d_surface_destroy(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - surface_cleanup(surface); - surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); - HeapFree(GetProcessHeap(), 0, surface); -#endif /* STAGING_CSMT */ -} - -void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, - unsigned int *width, unsigned int *height) -{ - if (surface->container->swapchain) - { - /* The drawable size of an onscreen drawable is the surface size. - * (Actually: The window size, but the surface is created in window - * size.) */ - *width = context->current_rt->resource.width; - *height = context->current_rt->resource.height; - } - else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) - { - const struct wined3d_swapchain *swapchain = context->swapchain; - - /* The drawable size of a backbuffer / aux buffer offscreen target is - * the size of the current context's drawable, which is the size of - * the back buffer of the swapchain the active context belongs to. */ - *width = swapchain->desc.backbuffer_width; - *height = swapchain->desc.backbuffer_height; - } - else - { - /* The drawable size of an FBO target is the OpenGL texture size, - * which is the power of two size. */ - *width = context->current_rt->pow2Width; - *height = context->current_rt->pow2Height; - } -} +static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM + | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; struct blt_info { GLenum binding; GLenum bind_target; enum wined3d_gl_resource_type tex_type; - GLfloat coords[4][3]; + struct wined3d_vec3 texcoords[4]; }; struct float_rect @@ -214,43 +60,43 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLsizei h, struct blt_info *info) { - GLfloat (*coords)[3] = info->coords; + struct wined3d_vec3 *coords = info->texcoords; struct float_rect f; switch (target) { default: - FIXME("Unsupported texture target %#x\n", target); + FIXME("Unsupported texture target %#x.\n", target); /* Fall back to GL_TEXTURE_2D */ case GL_TEXTURE_2D: info->binding = GL_TEXTURE_BINDING_2D; info->bind_target = GL_TEXTURE_2D; info->tex_type = WINED3D_GL_RES_TYPE_TEX_2D; - coords[0][0] = (float)rect->left / w; - coords[0][1] = (float)rect->top / h; - coords[0][2] = 0.0f; + coords[0].x = (float)rect->left / w; + coords[0].y = (float)rect->top / h; + coords[0].z = 0.0f; - coords[1][0] = (float)rect->right / w; - coords[1][1] = (float)rect->top / h; - coords[1][2] = 0.0f; + coords[1].x = (float)rect->right / w; + coords[1].y = (float)rect->top / h; + coords[1].z = 0.0f; - coords[2][0] = (float)rect->left / w; - coords[2][1] = (float)rect->bottom / h; - coords[2][2] = 0.0f; + coords[2].x = (float)rect->left / w; + coords[2].y = (float)rect->bottom / h; + coords[2].z = 0.0f; - coords[3][0] = (float)rect->right / w; - coords[3][1] = (float)rect->bottom / h; - coords[3][2] = 0.0f; + coords[3].x = (float)rect->right / w; + coords[3].y = (float)rect->bottom / h; + coords[3].z = 0.0f; break; case GL_TEXTURE_RECTANGLE_ARB: info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; info->bind_target = GL_TEXTURE_RECTANGLE_ARB; info->tex_type = WINED3D_GL_RES_TYPE_TEX_RECT; - coords[0][0] = rect->left; coords[0][1] = rect->top; coords[0][2] = 0.0f; - coords[1][0] = rect->right; coords[1][1] = rect->top; coords[1][2] = 0.0f; - coords[2][0] = rect->left; coords[2][1] = rect->bottom; coords[2][2] = 0.0f; - coords[3][0] = rect->right; coords[3][1] = rect->bottom; coords[3][2] = 0.0f; + coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; + coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; + coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; + coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_X: @@ -259,10 +105,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l; - coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r; - coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l; - coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r; + coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; + coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; + coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; + coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: @@ -271,10 +117,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l; - coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r; - coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l; - coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r; + coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; + coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; + coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; + coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -283,10 +129,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t; - coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t; - coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b; - coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b; + coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; + coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; + coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; + coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: @@ -295,10 +141,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t; - coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t; - coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b; - coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b; + coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; + coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; + coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; + coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: @@ -307,10 +153,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f; - coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f; - coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f; - coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f; + coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; + coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; + coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; + coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: @@ -319,27 +165,14 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f; - coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f; - coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f; - coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f; + coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; + coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; + coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; + coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; break; } } -static void surface_get_rect(const struct wined3d_surface *surface, const RECT *rect_in, RECT *rect_out) -{ - if (rect_in) - *rect_out = *rect_in; - else - { - rect_out->left = 0; - rect_out->top = 0; - rect_out->right = surface->resource.width; - rect_out->bottom = surface->resource.height; - } -} - /* Context activation is done by the caller. */ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) @@ -348,7 +181,9 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 struct wined3d_texture *texture = src_surface->container; struct blt_info info; - surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info); + surface_get_blt_info(src_surface->texture_target, src_rect, + wined3d_texture_get_level_pow2_width(texture, src_surface->texture_level), + wined3d_texture_get_level_pow2_height(texture, src_surface->texture_level), &info); gl_info->gl_ops.gl.p_glEnable(info.bind_target); checkGLcall("glEnable(bind_target)"); @@ -370,16 +205,16 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 /* Draw a quad */ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); gl_info->gl_ops.gl.p_glEnd(); @@ -402,413 +237,15 @@ static void get_color_masks(const struct wined3d_format *format, DWORD *masks) masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset; } -HRESULT surface_create_dib_section(struct wined3d_surface *surface) -{ - const struct wined3d_format *format = surface->resource.format; - unsigned int format_flags = surface->container->resource.format_flags; - unsigned int row_pitch, slice_pitch; - BITMAPINFO *b_info; - DWORD *masks; - - TRACE("surface %p.\n", surface); - - if (!(format_flags & WINED3DFMT_FLAG_GETDC)) - { - WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(format->id)); - return WINED3DERR_INVALIDCALL; - } - - switch (format->byte_count) - { - case 2: - case 4: - /* Allocate extra space to store the RGB bit masks. */ - b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO, bmiColors[3])); - break; - - case 3: - b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO, bmiColors[0])); - break; - - default: - /* Allocate extra space for a palette. */ - b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - FIELD_OFFSET(BITMAPINFO, bmiColors[1u << (format->byte_count * 8)])); - break; - } - - if (!b_info) - return E_OUTOFMEMORY; - - b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch); -#else /* STAGING_CSMT */ - wined3d_texture_get_pitch(surface->container, surface->texture_level, &row_pitch, &slice_pitch); -#endif /* STAGING_CSMT */ - b_info->bmiHeader.biWidth = row_pitch / format->byte_count; - b_info->bmiHeader.biHeight = 0 - surface->resource.height; - b_info->bmiHeader.biSizeImage = slice_pitch; - b_info->bmiHeader.biPlanes = 1; - b_info->bmiHeader.biBitCount = format->byte_count * 8; - - b_info->bmiHeader.biXPelsPerMeter = 0; - b_info->bmiHeader.biYPelsPerMeter = 0; - b_info->bmiHeader.biClrUsed = 0; - b_info->bmiHeader.biClrImportant = 0; - - /* Get the bit masks */ - masks = (DWORD *)b_info->bmiColors; - switch (surface->resource.format->id) - { - case WINED3DFMT_B8G8R8_UNORM: - b_info->bmiHeader.biCompression = BI_RGB; - break; - - case WINED3DFMT_B5G5R5X1_UNORM: - case WINED3DFMT_B5G5R5A1_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - case WINED3DFMT_B4G4R4X4_UNORM: - case WINED3DFMT_B2G3R3_UNORM: - case WINED3DFMT_B2G3R3A8_UNORM: - case WINED3DFMT_R10G10B10A2_UNORM: - case WINED3DFMT_R8G8B8A8_UNORM: - case WINED3DFMT_R8G8B8X8_UNORM: - case WINED3DFMT_B10G10R10A2_UNORM: - case WINED3DFMT_B5G6R5_UNORM: - case WINED3DFMT_R16G16B16A16_UNORM: - b_info->bmiHeader.biCompression = BI_BITFIELDS; - get_color_masks(format, masks); - break; - - default: - /* Don't know palette */ - b_info->bmiHeader.biCompression = BI_RGB; - break; - } - - TRACE("Creating a DIB section with size %dx%dx%d, size=%d.\n", - b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight, - b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage); -#if defined(STAGING_CSMT) - surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->resource.bitmap_data, 0, 0); -#else /* STAGING_CSMT */ - surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->dib.bitmap_data, 0, 0); -#endif /* STAGING_CSMT */ - - if (!surface->dib.DIBsection) - { - ERR("Failed to create DIB section.\n"); - HeapFree(GetProcessHeap(), 0, b_info); - return HRESULT_FROM_WIN32(GetLastError()); - } - -#if defined(STAGING_CSMT) - TRACE("DIBSection at %p.\n", surface->resource.bitmap_data); -#else /* STAGING_CSMT */ - TRACE("DIBSection at %p.\n", surface->dib.bitmap_data); -#endif /* STAGING_CSMT */ - surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage; - - HeapFree(GetProcessHeap(), 0, b_info); - - /* Now allocate a DC. */ - surface->hDC = CreateCompatibleDC(0); - SelectObject(surface->hDC, surface->dib.DIBsection); - - surface->flags |= SFLAG_DIBSECTION; - - return WINED3D_OK; -} - -#if !defined(STAGING_CSMT) -static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, - DWORD location) -{ - if (location & WINED3D_LOCATION_BUFFER) - { - data->addr = NULL; - data->buffer_object = surface->pbo; - return; - } - if (location & WINED3D_LOCATION_USER_MEMORY) - { - data->addr = surface->container->user_memory; - data->buffer_object = 0; - return; - } - if (location & WINED3D_LOCATION_DIB) - { - data->addr = surface->dib.bitmap_data; - data->buffer_object = 0; - return; - } - if (location & WINED3D_LOCATION_SYSMEM) - { - data->addr = surface->resource.heap_memory; - data->buffer_object = 0; - return; - } - - ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); - data->addr = NULL; - data->buffer_object = 0; -} - -static void surface_prepare_buffer(struct wined3d_surface *surface) -{ - struct wined3d_context *context; - GLenum error; - const struct wined3d_gl_info *gl_info; - - if (surface->pbo) - return; - - context = context_acquire(surface->resource.device, NULL); - gl_info = context->gl_info; - - GL_EXTCALL(glGenBuffers(1, &surface->pbo)); - error = gl_info->gl_ops.gl.p_glGetError(); - if (!surface->pbo || error != GL_NO_ERROR) - ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); - - TRACE("Binding PBO %u.\n", surface->pbo); - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); - checkGLcall("glBindBuffer"); - - GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, - NULL, GL_STREAM_DRAW)); - checkGLcall("glBufferData"); - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - - context_release(context); -} - -static void surface_prepare_system_memory(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - if (surface->resource.heap_memory) - return; - - /* Whatever surface we have, make sure that there is memory allocated - * for the downloaded copy, or a PBO to map. */ - if (!wined3d_resource_allocate_sysmem(&surface->resource)) - ERR("Failed to allocate system memory.\n"); - - if (surface->locations & WINED3D_LOCATION_SYSMEM) - ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); -} - -void surface_prepare_map_memory(struct wined3d_surface *surface) -{ - switch (surface->resource.map_binding) - { - case WINED3D_LOCATION_SYSMEM: - surface_prepare_system_memory(surface); - break; - - case WINED3D_LOCATION_USER_MEMORY: - if (!surface->container->user_memory) - ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); - break; - - case WINED3D_LOCATION_DIB: - if (!surface->dib.bitmap_data) - ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->dib.bitmap_data is NULL.\n"); - break; - - case WINED3D_LOCATION_BUFFER: - surface_prepare_buffer(surface); - break; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); - } -} - -#endif /* STAGING_CSMT */ -static void surface_evict_sysmem(struct wined3d_surface *surface) -{ - /* In some conditions the surface memory must not be freed: - * WINED3D_TEXTURE_CONVERTED: Converting the data back would take too long - * WINED3D_TEXTURE_DYNAMIC_MAP: Avoid freeing the data for performance */ - if (surface->resource.map_count || surface->container->flags & (WINED3D_TEXTURE_CONVERTED - | WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_DYNAMIC_MAP)) - return; - - wined3d_resource_free_sysmem(&surface->resource); -#if defined(STAGING_CSMT) - surface->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); -#else /* STAGING_CSMT */ - surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); -#endif /* STAGING_CSMT */ -} - -static BOOL surface_use_pbo(const struct wined3d_surface *surface) -{ - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; - struct wined3d_texture *texture = surface->container; - - return texture->resource.pool == WINED3D_POOL_DEFAULT - && surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] - && !texture->resource.format->convert - && !(texture->flags & WINED3D_TEXTURE_PIN_SYSMEM) - && !(texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED); -} - -static HRESULT surface_private_setup(struct wined3d_surface *surface) -{ - /* TODO: Check against the maximum texture sizes supported by the video card. */ - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; - unsigned int pow2Width, pow2Height; - - TRACE("surface %p.\n", surface); - - /* Non-power2 support */ - if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] - || gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - pow2Width = surface->resource.width; - pow2Height = surface->resource.height; - } - else - { - /* Find the nearest pow2 match */ - pow2Width = pow2Height = 1; - while (pow2Width < surface->resource.width) - pow2Width <<= 1; - while (pow2Height < surface->resource.height) - pow2Height <<= 1; - } - surface->pow2Width = pow2Width; - surface->pow2Height = pow2Height; - - if (pow2Width > surface->resource.width || pow2Height > surface->resource.height) - { - /* TODO: Add support for non power two compressed textures. */ - if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_HEIGHT_SCALE)) - { - FIXME("(%p) Compressed or height scaled non-power-two textures are not supported w(%d) h(%d)\n", - surface, surface->resource.width, surface->resource.height); - return WINED3DERR_NOTAVAILABLE; - } - } - - if ((surface->pow2Width > gl_info->limits.texture_size || surface->pow2Height > gl_info->limits.texture_size) - && !(surface->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) - { - /* One of three options: - * 1: Do the same as we do with NPOT and scale the texture, (any - * texture ops would require the texture to be scaled which is - * potentially slow) - * 2: Set the texture to the maximum size (bad idea). - * 3: WARN and return WINED3DERR_NOTAVAILABLE; - * 4: Create the surface, but allow it to be used only for DirectDraw - * Blts. Some apps (e.g. Swat 3) create textures with a Height of - * 16 and a Width > 3000 and blt 16x16 letter areas from them to - * the render target. */ - if (surface->resource.pool == WINED3D_POOL_DEFAULT || surface->resource.pool == WINED3D_POOL_MANAGED) - { - WARN("Unable to allocate a surface which exceeds the maximum OpenGL texture size.\n"); - return WINED3DERR_NOTAVAILABLE; - } - - /* We should never use this surface in combination with OpenGL! */ - TRACE("Creating an oversized surface: %ux%u.\n", - surface->pow2Width, surface->pow2Height); - } - - if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) -#if defined(STAGING_CSMT) - surface->resource.locations = WINED3D_LOCATION_DISCARDED; -#else /* STAGING_CSMT */ - surface->locations = WINED3D_LOCATION_DISCARDED; -#endif /* STAGING_CSMT */ - - if (surface_use_pbo(surface)) - surface->resource.map_binding = WINED3D_LOCATION_BUFFER; - - return WINED3D_OK; -} - -#if defined(STAGING_CSMT) -static void surface_frontbuffer_updated(struct wined3d_surface *surface) -{ - struct wined3d_context *context = NULL; - struct wined3d_device *device = surface->resource.device; - - if (surface->resource.locations & WINED3D_LOCATION_DRAWABLE) - { - TRACE("Not dirtified, nothing to do.\n"); - return; - } - - if (device->d3d_initialized) - context = context_acquire(surface->resource.device, NULL); - wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); - if (context) - context_release(context); -#else /* STAGING_CSMT */ -static void surface_unmap(struct wined3d_surface *surface) -{ - struct wined3d_device *device = surface->resource.device; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - TRACE("surface %p.\n", surface); - - memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - - switch (surface->resource.map_binding) - { - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_USER_MEMORY: - case WINED3D_LOCATION_DIB: - break; - - case WINED3D_LOCATION_BUFFER: - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glUnmapBuffer"); - context_release(context); - break; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); - } - - if (surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) - { - TRACE("Not dirtified, nothing to do.\n"); - return; - } - - if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container) - { - context = context_acquire(device, surface); - surface_load_location(surface, context, surface->container->resource.draw_binding); - context_release(context); - } - else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) - FIXME("Depth / stencil buffer locking is not implemented.\n"); -#endif /* STAGING_CSMT */ -} - static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) { - if ((r->left && r->right) || abs(r->right - r->left) != surface->resource.width) + unsigned int t; + + t = wined3d_texture_get_level_width(surface->container, surface->texture_level); + if ((r->left && r->right) || abs(r->right - r->left) != t) return FALSE; - if ((r->top && r->bottom) || abs(r->bottom - r->top) != surface->resource.height) + t = wined3d_texture_get_level_height(surface->container, surface->texture_level); + if ((r->top && r->bottom) || abs(r->bottom - r->top) != t) return FALSE; return TRUE; } @@ -817,6 +254,10 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect) { + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; DWORD src_mask, dst_mask; @@ -828,21 +269,21 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n", dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect)); - src_mask = src_surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - dst_mask = dst_surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + src_mask = src_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + dst_mask = dst_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); if (src_mask != dst_mask) { ERR("Incompatible formats %s and %s.\n", - debug_d3dformat(src_surface->resource.format->id), - debug_d3dformat(dst_surface->resource.format->id)); + debug_d3dformat(src_texture->resource.format->id), + debug_d3dformat(dst_texture->resource.format->id)); return; } if (!src_mask) { ERR("Not a depth / stencil format: %s.\n", - debug_d3dformat(src_surface->resource.format->id)); + debug_d3dformat(src_texture->resource.format->id)); return; } @@ -852,7 +293,7 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, if (src_mask & WINED3DFMT_FLAG_STENCIL) gl_mask |= GL_STENCIL_BUFFER_BIT; - context = context_acquire(device, NULL); + context = context_acquire(device, NULL, 0); if (!context->valid) { context_release(context); @@ -862,17 +303,11 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. */ -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, context, src_location); + wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location); if (!surface_is_full_rect(dst_surface, dst_rect)) - wined3d_resource_load_location(&dst_surface->resource, context, dst_location); -#else /* STAGING_CSMT */ - surface_load_location(src_surface, context, src_location); - if (!surface_is_full_rect(dst_surface, dst_rect)) - surface_load_location(dst_surface, context, dst_location); -#endif /* STAGING_CSMT */ + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); else - wined3d_surface_prepare(dst_surface, context, dst_location); + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); gl_info = context->gl_info; @@ -920,6 +355,10 @@ static void surface_blt_fbo(const struct wined3d_device *device, struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in) { + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; const struct wined3d_gl_info *gl_info; struct wined3d_context *context = old_ctx; struct wined3d_surface *required_rt, *restore_rt = NULL; @@ -952,7 +391,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, /* Resolve the source surface first if needed. */ if (src_location == WINED3D_LOCATION_RB_MULTISAMPLE - && (src_surface->resource.format->id != dst_surface->resource.format->id + && (src_texture->resource.format->id != dst_texture->resource.format->id || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top) || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left))) src_location = WINED3D_LOCATION_RB_RESOLVED; @@ -961,28 +400,23 @@ static void surface_blt_fbo(const struct wined3d_device *device, * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with * the purpose of loading the destination surface.) */ -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, old_ctx, src_location); + wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location); if (!surface_is_full_rect(dst_surface, &dst_rect)) - wined3d_resource_load_location(&dst_surface->resource, old_ctx, dst_location); -#else /* STAGING_CSMT */ - surface_load_location(src_surface, old_ctx, src_location); - if (!surface_is_full_rect(dst_surface, &dst_rect)) - surface_load_location(dst_surface, old_ctx, dst_location); -#endif /* STAGING_CSMT */ + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); else - wined3d_surface_prepare(dst_surface, old_ctx, dst_location); + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location); if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface; else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface; else required_rt = NULL; - if (required_rt && required_rt != old_ctx->current_rt) - { - restore_rt = old_ctx->current_rt; - context = context_acquire(device, required_rt); - } + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != required_rt) + context = context_acquire(device, required_rt ? required_rt->container : NULL, + required_rt ? surface_get_sub_resource_idx(required_rt) : 0); + else + restore_rt = NULL; if (!context->valid) { @@ -996,7 +430,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, if (src_location == WINED3D_LOCATION_DRAWABLE) { TRACE("Source surface %p is onscreen.\n", src_surface); - buffer = surface_get_gl_buffer(src_surface); + buffer = wined3d_texture_get_gl_buffer(src_texture); surface_translate_drawable_coords(src_surface, context->win_handle, &src_rect); } else @@ -1013,7 +447,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, if (dst_location == WINED3D_LOCATION_DRAWABLE) { TRACE("Destination surface %p is onscreen.\n", dst_surface); - buffer = surface_get_gl_buffer(dst_surface); + buffer = wined3d_texture_get_gl_buffer(dst_texture); surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect); } else @@ -1040,18 +474,17 @@ static void surface_blt_fbo(const struct wined3d_device *device, dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("glBlitFramebuffer()"); - if (wined3d_settings.strict_draw_ordering - || (dst_location == WINED3D_LOCATION_DRAWABLE - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) + if (wined3d_settings.strict_draw_ordering || (dst_location == WINED3D_LOCATION_DRAWABLE + && dst_texture->swapchain->front_buffer == dst_texture)) gl_info->gl_ops.gl.p_glFlush(); if (restore_rt) context_restore(context, restore_rt); } -static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) +static BOOL fbo_blitter_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op, + DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location, + DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location) { if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer) return FALSE; @@ -1069,9 +502,8 @@ static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET))) return FALSE; - if (!(src_format->id == dst_format->id - || (is_identity_fixup(src_format->color_fixup) - && is_identity_fixup(dst_format->color_fixup)))) + if ((src_format->id != dst_format->id || dst_location == WINED3D_LOCATION_DRAWABLE) + && (!is_identity_fixup(src_format->color_fixup) || !is_identity_fixup(dst_format->color_fixup))) return FALSE; break; @@ -1095,521 +527,184 @@ static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined return TRUE; } -static BOOL surface_convert_depth_to_float(const struct wined3d_surface *surface, DWORD depth, float *float_depth) -{ - const struct wined3d_format *format = surface->resource.format; - - switch (format->id) - { - case WINED3DFMT_S1_UINT_D15_UNORM: - *float_depth = depth / (float)0x00007fff; - break; - - case WINED3DFMT_D16_UNORM: - *float_depth = depth / (float)0x0000ffff; - break; - - case WINED3DFMT_D24_UNORM_S8_UINT: - case WINED3DFMT_X8D24_UNORM: - *float_depth = depth / (float)0x00ffffff; - break; - - case WINED3DFMT_D32_UNORM: - *float_depth = depth / (float)0xffffffff; - break; - - default: - ERR("Unhandled conversion from %s to floating point.\n", debug_d3dformat(format->id)); - return FALSE; - } - - return TRUE; -} - -static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const RECT *rect, float depth) -{ - struct wined3d_resource *resource = &surface->container->resource; - struct wined3d_device *device = resource->device; -#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view view; - struct wined3d_texture *texture = surface->container; -#else /* STAGING_CSMT */ - struct wined3d_rendertarget_view_desc view_desc; - struct wined3d_rendertarget_view *view; -#endif /* STAGING_CSMT */ - const struct blit_shader *blitter; - HRESULT hr; - - if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, - WINED3D_BLIT_OP_DEPTH_FILL, NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format))) - { - FIXME("No blitter is capable of performing the requested depth fill operation.\n"); - return WINED3DERR_INVALIDCALL; - } - -#if defined(STAGING_CSMT) - view.resource = &surface->container->resource; - view.parent = NULL; - view.parent_ops = &wined3d_null_parent_ops; - view.format = surface->resource.format; - view.buffer_offset = 0; - view.width = surface->resource.width; - view.height = surface->resource.height; - view.depth = 1; - view.sub_resource_idx = surface->texture_layer * texture->level_count + surface->texture_level; - - hr = blitter->depth_fill(device, &view, rect, depth); -#else /* STAGING_CSMT */ - view_desc.format_id = resource->format->id; - view_desc.u.texture.level_idx = surface->texture_level; - view_desc.u.texture.layer_idx = surface->texture_layer; - view_desc.u.texture.layer_count = 1; - if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, - resource, NULL, &wined3d_null_parent_ops, &view))) - { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - return hr; - } - - hr = blitter->depth_fill(device, view, rect, depth); - wined3d_rendertarget_view_decref(view); -#endif /* STAGING_CSMT */ - - return hr; -} - -static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, - struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect) -{ - struct wined3d_device *device = src_surface->resource.device; - - if (!fbo_blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_DEPTH_BLIT, - src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) - return WINED3DERR_INVALIDCALL; - - surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect); - - surface_modify_ds_location(dst_surface, dst_location, - dst_surface->ds_current_size.cx, dst_surface->ds_current_size.cy); - - return WINED3D_OK; -} - -#if !defined(STAGING_CSMT) -/* Context activation is done by the caller. */ -static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) -{ - GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); - checkGLcall("glDeleteBuffers(1, &surface->pbo)"); - - surface->pbo = 0; - surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); -} - -#endif /* STAGING_CSMT */ -static ULONG surface_resource_incref(struct wined3d_resource *resource) -{ - struct wined3d_surface *surface = surface_from_resource(resource); - - TRACE("surface %p, container %p.\n", surface, surface->container); - - return wined3d_texture_incref(surface->container); -} - -static ULONG surface_resource_decref(struct wined3d_resource *resource) -{ - struct wined3d_surface *surface = surface_from_resource(resource); - - TRACE("surface %p, container %p.\n", surface, surface->container); - - return wined3d_texture_decref(surface->container); -} - -static void surface_unload(struct wined3d_resource *resource) -{ - struct wined3d_surface *surface = surface_from_resource(resource); - struct wined3d_renderbuffer_entry *entry, *entry2; - struct wined3d_device *device = resource->device; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - TRACE("surface %p.\n", surface); - - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - if (resource->pool == WINED3D_POOL_DEFAULT) - { -#if defined(STAGING_CSMT) - /* Default pool resources are supposed to be destroyed before Reset is called. - * Implicit resources stay however. So this means we have an implicit render target - * or depth stencil. The content may be destroyed, but we still have to tear down - * opengl resources, so we cannot leave early. */ - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DISCARDED); - wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DISCARDED); - } - else - { - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); - } -#else /* STAGING_CSMT */ - /* Default pool resources are supposed to be destroyed before Reset is called. - * Implicit resources stay however. So this means we have an implicit render target - * or depth stencil. The content may be destroyed, but we still have to tear down - * opengl resources, so we cannot leave early. - * - * Put the surfaces into sysmem, and reset the content. The D3D content is undefined, - * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain - * or the depth stencil into an FBO the texture or render buffer will be removed - * and all flags get lost */ - if (resource->usage & WINED3DUSAGE_DEPTHSTENCIL) - { - surface_validate_location(surface, WINED3D_LOCATION_DISCARDED); - surface_invalidate_location(surface, ~WINED3D_LOCATION_DISCARDED); - } - else - { - surface_prepare_system_memory(surface); - memset(surface->resource.heap_memory, 0, surface->resource.size); - surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); - surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM); - } - } - else - { - surface_prepare_map_memory(surface); - surface_load_location(surface, context, surface->resource.map_binding); - surface_invalidate_location(surface, ~surface->resource.map_binding); - } - - /* Destroy PBOs, but load them into real sysmem before */ - if (surface->pbo) - surface_remove_pbo(surface, gl_info); -#endif /* STAGING_CSMT */ - - /* Destroy fbo render buffers. This is needed for implicit render targets, for - * all application-created targets the application has to release the surface - * before calling _Reset - */ - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) - { - gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); - list_remove(&entry->entry); - HeapFree(GetProcessHeap(), 0, entry); - } - list_init(&surface->renderbuffers); - surface->current_renderbuffer = NULL; - - if (surface->rb_multisample) - { - gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample); - surface->rb_multisample = 0; - } - if (surface->rb_resolved) - { - gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved); - surface->rb_resolved = 0; - } - - context_release(context); - - resource_unload(resource); -} - -static HRESULT surface_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - ERR("Not supported on sub-resources.\n"); - return WINED3DERR_INVALIDCALL; -} - -static HRESULT surface_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -{ - ERR("Not supported on sub-resources.\n"); - return WINED3DERR_INVALIDCALL; -} - -#if defined(STAGING_CSMT) -static void wined3d_surface_location_invalidated(struct wined3d_resource *resource, DWORD location) -{ - struct wined3d_surface *surface = surface_from_resource(resource); - - if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - wined3d_texture_set_dirty(surface->container); - - if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) - surface->surface_ops->surface_frontbuffer_updated(surface); -} - -static const struct wined3d_surface_ops surface_ops = -{ - surface_private_setup, - surface_frontbuffer_updated, -#else /* STAGING_CSMT */ -static const struct wined3d_resource_ops surface_resource_ops = -{ - surface_resource_incref, - surface_resource_decref, - surface_unload, - surface_resource_sub_resource_map, - surface_resource_sub_resource_unmap, -}; - -static const struct wined3d_surface_ops surface_ops = -{ - surface_private_setup, - surface_unmap, -#endif /* STAGING_CSMT */ -}; - -/***************************************************************************** - * Initializes the GDI surface, aka creates the DIB section we render to - * The DIB section creation is done by calling GetDC, which will create the - * section and releasing the dc to allow the app to use it. The dib section - * will stay until the surface is released - * - * GDI surfaces do not need to be a power of 2 in size, so the pow2 sizes - * are set to the real sizes to save memory. The NONPOW2 flag is unset to - * avoid confusion in the shared surface code. - * - * Returns: - * WINED3D_OK on success - * The return values of called methods on failure - * - *****************************************************************************/ -static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface) -{ - HRESULT hr; - - TRACE("surface %p.\n", surface); - - if (surface->resource.usage & WINED3DUSAGE_OVERLAY) - { - ERR("Overlays not yet supported by GDI surfaces.\n"); - return WINED3DERR_INVALIDCALL; - } - - /* Sysmem textures have memory already allocated - release it, - * this avoids an unnecessary memcpy. */ - hr = surface_create_dib_section(surface); - if (FAILED(hr)) - return hr; - surface->resource.map_binding = WINED3D_LOCATION_DIB; - - /* We don't mind the nonpow2 stuff in GDI. */ - surface->pow2Width = surface->resource.width; - surface->pow2Height = surface->resource.height; - - return WINED3D_OK; -} - -#if defined(STAGING_CSMT) -static void gdi_surface_frontbuffer_updated(struct wined3d_surface *surface) -{ - x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); -} - -static const struct wined3d_surface_ops gdi_surface_ops = -{ - gdi_surface_private_setup, - gdi_surface_frontbuffer_updated, -#else /* STAGING_CSMT */ -static void gdi_surface_unmap(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - /* Tell the swapchain to update the screen. */ - if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) - x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); - - memset(&surface->lockedRect, 0, sizeof(RECT)); -} - -static const struct wined3d_surface_ops gdi_surface_ops = -{ - gdi_surface_private_setup, - gdi_surface_unmap, -#endif /* STAGING_CSMT */ -}; - /* This call just downloads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, DWORD dst_location) { - const struct wined3d_format *format = surface->resource.format; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; + const struct wined3d_format *format = texture->resource.format; + struct wined3d_texture_sub_resource *sub_resource; + unsigned int dst_row_pitch, dst_slice_pitch; + unsigned int src_row_pitch, src_slice_pitch; struct wined3d_bo_address data; + BYTE *temporary_mem = NULL; + void *mem; /* Only support read back of converted P8 surfaces. */ - if (surface->container->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT) + if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT) { ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id)); return; } -#if defined(STAGING_CSMT) - wined3d_resource_get_memory(&surface->resource, dst_location, &data); -#else /* STAGING_CSMT */ - surface_get_memory(surface, &data, dst_location); -#endif /* STAGING_CSMT */ + sub_resource = &texture->sub_resources[sub_resource_idx]; - if (surface->container->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) { - TRACE("(%p) : Calling glGetCompressedTexImage level %d, format %#x, type %#x, data %p.\n", - surface, surface->texture_level, format->glFormat, format->glType, data.addr); + /* NP2 emulation is not allowed on array textures. */ + if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + ERR("Array texture %p uses NP2 emulation.\n", texture); + + WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + + if (!(temporary_mem = wined3d_calloc(texture->layer_count, sub_resource->size))) + { + ERR("Out of memory.\n"); + return; + } + } + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); + + if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + { + wined3d_texture_get_pitch(texture, surface->texture_level, &dst_row_pitch, &dst_slice_pitch); + wined3d_format_calculate_pitch(format, texture->resource.device->surface_alignment, + wined3d_texture_get_level_pow2_width(texture, surface->texture_level), + wined3d_texture_get_level_pow2_height(texture, surface->texture_level), + &src_row_pitch, &src_slice_pitch); + if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch))) + { + ERR("Out of memory.\n"); + return; + } if (data.buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); - checkGLcall("glBindBuffer"); - GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, NULL)); - checkGLcall("glGetCompressedTexImage"); - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - else - { - GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, - surface->texture_level, data.addr)); - checkGLcall("glGetCompressedTexImage"); - } + ERR("NP2 emulated texture uses PBO unexpectedly.\n"); + if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + ERR("Unexpected compressed format for NP2 emulated texture.\n"); + } + + if (temporary_mem) + { + mem = temporary_mem; + } + else if (data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); + checkGLcall("glBindBuffer"); + mem = data.addr; } else { - unsigned int dst_row_pitch, dst_slice_pitch; -#if defined(STAGING_CSMT) - unsigned int src_pitch; - GLenum gl_format = format->glFormat; - GLenum gl_type = format->glType; - void *mem; + mem = data.addr; + } - if (surface->container->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) - { - unsigned char alignment = surface->resource.device->surface_alignment; - src_pitch = format->byte_count * surface->pow2Width; - wined3d_resource_get_pitch(&surface->resource, &dst_row_pitch, &dst_slice_pitch); - src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1); - mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height); -#else /* STAGING_CSMT */ - unsigned int src_row_pitch, src_slice_pitch; - GLenum gl_format = format->glFormat; - GLenum gl_type = format->glType; - void *mem; + if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + { + TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n", + surface, surface->texture_level, format->glFormat, format->glType, mem); - if (surface->container->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, mem)); + checkGLcall("glGetCompressedTexImage"); + } + else + { + TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n", + surface, surface->texture_level, format->glFormat, format->glType, mem); + + gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level, + format->glFormat, format->glType, mem); + checkGLcall("glGetTexImage"); + } + + if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) + { + const BYTE *src_data; + unsigned int h, y; + BYTE *dst_data; + /* + * Some games (e.g. warhammer 40k) don't work properly with the odd pitches, preventing + * the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to + * repack the texture so that the bpp * width pitch can be used instead of bpp * pow2width. + * + * We're doing this... + * + * instead of boxing the texture : + * |<-texture width ->| -->pow2width| /\ + * |111111111111111111| | | + * |222 Texture 222222| boxed empty | texture height + * |3333 Data 33333333| | | + * |444444444444444444| | \/ + * ----------------------------------- | + * | boxed empty | boxed empty | pow2height + * | | | \/ + * ----------------------------------- + * + * + * we're repacking the data to the expected texture width + * + * |<-texture width ->| -->pow2width| /\ + * |111111111111111111222222222222222| | + * |222333333333333333333444444444444| texture height + * |444444 | | + * | | \/ + * | | | + * | empty | pow2height + * | | \/ + * ----------------------------------- + * + * == is the same as + * + * |<-texture width ->| /\ + * |111111111111111111| + * |222222222222222222|texture height + * |333333333333333333| + * |444444444444444444| \/ + * -------------------- + * + * This also means that any references to surface memory should work with the data as if it were a + * standard texture with a non-power2 width instead of a texture boxed up to be a power2 texture. + * + * internally the texture is still stored in a boxed format so any references to textureName will + * get a boxed texture with width pow2width and not a texture of width resource.width. */ + src_data = mem; + dst_data = data.addr; + TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch); + h = wined3d_texture_get_level_height(texture, surface->texture_level); + for (y = 0; y < h; ++y) { - wined3d_texture_get_pitch(surface->container, surface->texture_level, &dst_row_pitch, &dst_slice_pitch); - wined3d_format_calculate_pitch(format, surface->resource.device->surface_alignment, - surface->pow2Width, surface->pow2Height, &src_row_pitch, &src_slice_pitch); - mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch); -#endif /* STAGING_CSMT */ + memcpy(dst_data, src_data, dst_row_pitch); + src_data += src_row_pitch; + dst_data += dst_row_pitch; } - else - { - mem = data.addr; - } - - TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", - surface, surface->texture_level, gl_format, gl_type, mem); - + } + else if (temporary_mem) + { + void *src_data = temporary_mem + surface->texture_layer * sub_resource->size; if (data.buffer_object) { GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data.buffer_object)); checkGLcall("glBindBuffer"); - - gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level, - gl_format, gl_type, NULL); - checkGLcall("glGetTexImage"); - - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data)); + checkGLcall("glBufferSubData"); } else { - gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level, - gl_format, gl_type, mem); - checkGLcall("glGetTexImage"); - } - - if (surface->container->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) - { - const BYTE *src_data; - BYTE *dst_data; - UINT y; - /* - * Some games (e.g. warhammer 40k) don't work properly with the odd pitches, preventing - * the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to - * repack the texture so that the bpp * width pitch can be used instead of bpp * pow2width. - * - * We're doing this... - * - * instead of boxing the texture : - * |<-texture width ->| -->pow2width| /\ - * |111111111111111111| | | - * |222 Texture 222222| boxed empty | texture height - * |3333 Data 33333333| | | - * |444444444444444444| | \/ - * ----------------------------------- | - * | boxed empty | boxed empty | pow2height - * | | | \/ - * ----------------------------------- - * - * - * we're repacking the data to the expected texture width - * - * |<-texture width ->| -->pow2width| /\ - * |111111111111111111222222222222222| | - * |222333333333333333333444444444444| texture height - * |444444 | | - * | | \/ - * | | | - * | empty | pow2height - * | | \/ - * ----------------------------------- - * - * == is the same as - * - * |<-texture width ->| /\ - * |111111111111111111| - * |222222222222222222|texture height - * |333333333333333333| - * |444444444444444444| \/ - * -------------------- - * - * This also means that any references to surface memory should work with the data as if it were a - * standard texture with a non-power2 width instead of a texture boxed up to be a power2 texture. - * - * internally the texture is still stored in a boxed format so any references to textureName will - * get a boxed texture with width pow2width and not a texture of width resource.width. - * - * Performance should not be an issue, because applications normally do not lock the surfaces when - * rendering. If an app does, the WINED3D_TEXTURE_DYNAMIC_MAP flag will kick in and the memory copy - * won't be released, and doesn't have to be re-read. */ - src_data = mem; - dst_data = data.addr; -#if defined(STAGING_CSMT) - TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_row_pitch); - for (y = 0; y < surface->resource.height; ++y) - { - memcpy(dst_data, src_data, dst_row_pitch); - src_data += src_pitch; -#else /* STAGING_CSMT */ - TRACE("Repacking the surface data from pitch %u to pitch %u.\n", src_row_pitch, dst_row_pitch); - for (y = 0; y < surface->resource.height; ++y) - { - memcpy(dst_data, src_data, dst_row_pitch); - src_data += src_row_pitch; -#endif /* STAGING_CSMT */ - dst_data += dst_row_pitch; - } - - HeapFree(GetProcessHeap(), 0, mem); + memcpy(data.addr, src_data, sub_resource->size); } } + + if (data.buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, temporary_mem); } /* This call just uploads data, the caller is responsible for binding the @@ -1619,6 +714,8 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, BOOL srgb, const struct wined3d_const_bo_address *data) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; UINT update_w = src_rect->right - src_rect->left; UINT update_h = src_rect->bottom - src_rect->top; @@ -1626,10 +723,10 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch, wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr); - if (surface->resource.map_count) + if (texture->sub_resources[sub_resource_idx].map_count) { WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n"); - surface->container->flags |= WINED3D_TEXTURE_PIN_SYSMEM; + texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; } if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) @@ -1646,8 +743,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) { - UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1, 1); - UINT row_count = (update_h + format->block_height - 1) / format->block_height; + unsigned int dst_row_pitch, dst_slice_pitch; const BYTE *addr = data->addr; GLenum internal; @@ -1656,36 +752,60 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w if (srgb) internal = format->glGammaInternal; - else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET - && wined3d_resource_is_offscreen(&surface->container->resource)) + else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET + && wined3d_resource_is_offscreen(&texture->resource)) internal = format->rtInternal; else internal = format->glInternal; - TRACE("glCompressedTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, " - "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level, - dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr); + wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch); - if (row_length == src_pitch) + TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, image_size %#x, addr %p.\n", + surface->texture_target, surface->texture_level, surface->texture_layer, + dst_point->x, dst_point->y, update_w, update_h, internal, dst_slice_pitch, addr); + + if (dst_row_pitch == src_pitch) { - GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr)); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1, + internal, dst_slice_pitch, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, update_w, update_h, + internal, dst_slice_pitch, addr)); + } } else { + UINT row_count = (update_h + format->block_height - 1) / format->block_height; UINT row, y; /* glCompressedTexSubImage2D() ignores pixel store state, so we * can't use the unpack row length like for glTexSubImage2D. */ for (row = 0, y = dst_point->y; row < row_count; ++row) { - GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, y, update_w, format->block_height, internal, row_length, addr)); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, y, surface->texture_layer, update_w, format->block_height, 1, + internal, dst_row_pitch, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, y, update_w, format->block_height, internal, dst_row_pitch, addr)); + } + y += format->block_height; addr += src_pitch; } } - checkGLcall("glCompressedTexSubImage2D"); + checkGLcall("Upload compressed surface data"); } else { @@ -1694,15 +814,25 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w addr += src_rect->top * src_pitch; addr += src_rect->left * format->byte_count; - TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, addr %p.\n", - surface->texture_target, surface->texture_level, dst_point->x, dst_point->y, - update_w, update_h, format->glFormat, format->glType, addr); + TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, type %#x, addr %p.\n", + surface->texture_target, surface->texture_level, surface->texture_layer, + dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count); - gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1, + format->glFormat, format->glType, addr)); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); + } gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - checkGLcall("glTexSubImage2D"); + checkGLcall("Upload surface data"); } if (data->buffer_object) @@ -1716,7 +846,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) { - struct wined3d_device *device = surface->resource.device; + struct wined3d_device *device = texture->resource.device; unsigned int i; for (i = 0; i < device->context_count; ++i) @@ -1726,165 +856,49 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w } } -#if defined(STAGING_CSMT) -static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box) -{ - if ((box->left >= box->right) - || (box->top >= box->bottom) - || (box->right > surface->resource.width) - || (box->bottom > surface->resource.height)) - return FALSE; - - return wined3d_resource_check_block_align(&surface->resource, box); -} - -static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) -{ - struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; - - return surface_check_block_align(surface, &box); -#else /* STAGING_CSMT */ -static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) -{ - struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; - - return wined3d_texture_check_block_align(surface->container, surface->texture_level, &box); -#endif /* STAGING_CSMT */ -} - -HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, +static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) { + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; unsigned int src_row_pitch, src_slice_pitch; - const struct wined3d_format *src_format; - const struct wined3d_format *dst_format; - unsigned int src_fmt_flags, dst_fmt_flags; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; struct wined3d_bo_address data; UINT update_w, update_h; - UINT dst_w, dst_h; - RECT r, dst_rect; - POINT p; TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n", dst_surface, wine_dbgstr_point(dst_point), src_surface, wine_dbgstr_rect(src_rect)); - src_format = src_surface->resource.format; - dst_format = dst_surface->resource.format; - src_fmt_flags = src_surface->container->resource.format_flags; - dst_fmt_flags = dst_surface->container->resource.format_flags; - - if (src_format->id != dst_format->id) - { - WARN("Source and destination surfaces should have the same format.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (!dst_point) - { - p.x = 0; - p.y = 0; - dst_point = &p; - } - else if (dst_point->x < 0 || dst_point->y < 0) - { - WARN("Invalid destination point.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (!src_rect) - { - r.left = 0; - r.top = 0; - r.right = src_surface->resource.width; - r.bottom = src_surface->resource.height; - src_rect = &r; - } - else if (src_rect->left < 0 || src_rect->left >= src_rect->right - || src_rect->top < 0 || src_rect->top >= src_rect->bottom) - { - WARN("Invalid source rectangle.\n"); - return WINED3DERR_INVALIDCALL; - } - - dst_w = dst_surface->resource.width; - dst_h = dst_surface->resource.height; - - update_w = src_rect->right - src_rect->left; - update_h = src_rect->bottom - src_rect->top; - - if (update_w > dst_w || dst_point->x > dst_w - update_w - || update_h > dst_h || dst_point->y > dst_h - update_h) - { - WARN("Destination out of bounds.\n"); - return WINED3DERR_INVALIDCALL; - } - - if ((src_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align_rect(src_surface, src_rect)) - { - WARN("Source rectangle not block-aligned.\n"); - return WINED3DERR_INVALIDCALL; - } - - SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h); - if ((dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align_rect(dst_surface, &dst_rect)) - { - WARN("Destination rectangle not block-aligned.\n"); - return WINED3DERR_INVALIDCALL; - } - -#if defined(STAGING_CSMT) - /* Use surface_cpu_blt() instead of uploading directly if we need - * conversion. Avoid calling wined3d_surface_blt() since that goes - * through the CS. */ - if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); -#else /* STAGING_CSMT */ - /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ - if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) - return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); -#endif /* STAGING_CSMT */ - - context = context_acquire(dst_surface->resource.device, NULL); + context = context_acquire(dst_texture->resource.device, NULL, 0); gl_info = context->gl_info; /* Only load the surface for partial updates. For newly allocated texture * the texture wouldn't be the current location, and we'd upload zeroes * just to overwrite them again. */ - if (update_w == dst_w && update_h == dst_h) - wined3d_texture_prepare_texture(dst_surface->container, context, FALSE); + update_w = src_rect->right - src_rect->left; + update_h = src_rect->bottom - src_rect->top; + if (update_w == wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level) + && update_h == wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level)) + wined3d_texture_prepare_texture(dst_texture, context, FALSE); else -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&dst_surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); - wined3d_resource_get_memory(&src_surface->resource, src_surface->resource.locations, &data); - wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, + src_texture->sub_resources[src_sub_resource_idx].locations); + wined3d_texture_get_pitch(src_texture, src_surface->texture_level, &src_row_pitch, &src_slice_pitch); - wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, + wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect, src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); context_release(context); - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -#else /* STAGING_CSMT */ - surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); - - surface_get_memory(src_surface, &data, src_surface->locations); - wined3d_texture_get_pitch(src_surface->container, src_surface->texture_level, &src_row_pitch, &src_slice_pitch); - - wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, - src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); - - context_release(context); - - surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); - surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); -#endif /* STAGING_CSMT */ + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); return WINED3D_OK; } @@ -1893,27 +907,38 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ /* Context activation is done by the caller. */ -void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_surface *rt) +void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt) { - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &surface->container->resource.device->adapter->gl_info; struct wined3d_renderbuffer_entry *entry; - GLuint renderbuffer = 0; unsigned int src_width, src_height; unsigned int width, height; + GLuint renderbuffer = 0; - if (rt && rt->resource.format->id != WINED3DFMT_NULL) + if (rt && rt->resource->format->id != WINED3DFMT_NULL) { - width = rt->pow2Width; - height = rt->pow2Height; + struct wined3d_texture *texture; + unsigned int level; + + if (rt->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); + return; + } + texture = wined3d_texture_from_resource(rt->resource); + level = rt->sub_resource_idx % texture->level_count; + + width = wined3d_texture_get_level_pow2_width(texture, level); + height = wined3d_texture_get_level_pow2_height(texture, level); } else { - width = surface->pow2Width; - height = surface->pow2Height; + width = wined3d_texture_get_level_pow2_width(surface->container, surface->texture_level); + height = wined3d_texture_get_level_pow2_height(surface->container, surface->texture_level); } - src_width = surface->pow2Width; - src_height = surface->pow2Height; + src_width = wined3d_texture_get_level_pow2_width(surface->container, surface->texture_level); + src_height = wined3d_texture_get_level_pow2_height(surface->container, surface->texture_level); /* A depth stencil smaller than the render target is not valid */ if (width > src_width || height > src_height) return; @@ -1942,7 +967,7 @@ void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, - surface->resource.format->glInternal, width, height); + surface->container->resource.format->glInternal, width, height); entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); entry->width = width; @@ -1956,70 +981,6 @@ void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const checkGLcall("set_compatible_renderbuffer"); } -GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) -{ - const struct wined3d_swapchain *swapchain = surface->container->swapchain; - - TRACE("surface %p.\n", surface); - - if (!swapchain) - { - ERR("Surface %p is not on a swapchain.\n", surface); - return GL_NONE; - } - - if (swapchain->back_buffers && swapchain->back_buffers[0] == surface->container) - { - if (swapchain->render_to_fbo) - { - TRACE("Returning GL_COLOR_ATTACHMENT0\n"); - return GL_COLOR_ATTACHMENT0; - } - TRACE("Returning GL_BACK\n"); - return GL_BACK; - } - else if (surface->container == swapchain->front_buffer) - { - TRACE("Returning GL_FRONT\n"); - return GL_FRONT; - } - - FIXME("Higher back buffer, returning GL_BACK\n"); - return GL_BACK; -} - -/* Context activation is done by the caller. */ -void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) -{ - DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - - TRACE("surface %p, srgb %#x.\n", surface, srgb); - - if (surface->resource.pool == WINED3D_POOL_SCRATCH) - ERR("Not supported on scratch surfaces.\n"); - -#if defined(STAGING_CSMT) - if (surface->resource.locations & location) - { - TRACE("surface is already in texture\n"); - return; - } - TRACE("Reloading because surface is dirty.\n"); - - wined3d_resource_load_location(&surface->resource, context, location); -#else /* STAGING_CSMT */ - if (surface->locations & location) - { - TRACE("surface is already in texture\n"); - return; - } - TRACE("Reloading because surface is dirty.\n"); - - surface_load_location(surface, context, location); -#endif /* STAGING_CSMT */ - surface_evict_sysmem(surface); -} - /* See also float_16_to_32() in wined3d_private.h */ static inline unsigned short float_32_to_16(const float *in) { @@ -2083,132 +1044,6 @@ static inline unsigned short float_32_to_16(const float *in) return ret; } -#if defined(STAGING_CSMT) -HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, - const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) -#else /* STAGING_CSMT */ -HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) -#endif /* STAGING_CSMT */ -{ - struct wined3d_resource *texture_resource = &surface->container->resource; - unsigned int width, height; - BOOL create_dib = FALSE; - DWORD valid_location = 0; - HRESULT hr; - - if (surface->flags & SFLAG_DIBSECTION) - { - DeleteDC(surface->hDC); - DeleteObject(surface->dib.DIBsection); -#if defined(STAGING_CSMT) - surface->resource.bitmap_data = NULL; - surface->flags &= ~SFLAG_DIBSECTION; - create_dib = TRUE; - } - - surface->resource.locations = 0; - wined3d_resource_free_sysmem(&surface->resource); - surface->resource.map_heap_memory = NULL; -#else /* STAGING_CSMT */ - surface->dib.bitmap_data = NULL; - surface->flags &= ~SFLAG_DIBSECTION; - create_dib = TRUE; - } - - surface->locations = 0; - wined3d_resource_free_sysmem(&surface->resource); -#endif /* STAGING_CSMT */ - - width = texture_resource->width; - height = texture_resource->height; - surface->resource.width = width; - surface->resource.height = height; - if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE] - || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - { - surface->pow2Width = width; - surface->pow2Height = height; - } - else - { - surface->pow2Width = surface->pow2Height = 1; - while (surface->pow2Width < width) - surface->pow2Width <<= 1; - while (surface->pow2Height < height) - surface->pow2Height <<= 1; - } - -#if defined(STAGING_CSMT) - if ((surface->resource.user_memory = mem)) - { - surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; - valid_location = WINED3D_LOCATION_USER_MEMORY; - } - surface->resource.custom_row_pitch = pitch; - surface->resource.custom_slice_pitch = pitch * surface->resource.height; - surface->resource.format = texture_resource->format; - surface->resource.multisample_type = texture_resource->multisample_type; - surface->resource.multisample_quality = texture_resource->multisample_quality; - if (surface->resource.custom_row_pitch) - { - surface->resource.size = height * surface->resource.custom_row_pitch; - } - else - { - /* User memory surfaces don't have the regular surface alignment. */ - surface->resource.size = wined3d_format_calculate_size(texture_resource->format, - 1, width, height, 1); - surface->resource.custom_row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width); - } -#else /* STAGING_CSMT */ - if (surface->container->user_memory) - { - surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; - valid_location = WINED3D_LOCATION_USER_MEMORY; - } - surface->resource.format = texture_resource->format; - surface->resource.multisample_type = texture_resource->multisample_type; - surface->resource.multisample_quality = texture_resource->multisample_quality; - surface->resource.size = surface->container->slice_pitch; -#endif /* STAGING_CSMT */ - - /* The format might be changed to a format that needs conversion. - * If the surface didn't use PBOs previously but could now, don't - * change it - whatever made us not use PBOs might come back, e.g. - * color keys. */ - if (surface->resource.map_binding == WINED3D_LOCATION_BUFFER && !surface_use_pbo(surface)) - surface->resource.map_binding = create_dib ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM; - - if (create_dib) - { - if (FAILED(hr = surface_create_dib_section(surface))) - { - ERR("Failed to create dib section, hr %#x.\n", hr); - return hr; - } - if (!valid_location) - valid_location = WINED3D_LOCATION_DIB; - } - - if (!valid_location) - { -#if defined(STAGING_CSMT) - wined3d_resource_prepare_system_memory(&surface->resource); - valid_location = WINED3D_LOCATION_SYSMEM; - } - - wined3d_resource_validate_location(&surface->resource, valid_location); -#else /* STAGING_CSMT */ - surface_prepare_system_memory(surface); - valid_location = WINED3D_LOCATION_SYSMEM; - } - - surface_validate_location(surface, valid_location); -#endif /* STAGING_CSMT */ - - return WINED3D_OK; -} - static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { @@ -2561,476 +1396,132 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo return NULL; } -static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) +static struct wined3d_texture *surface_convert_format(struct wined3d_texture *src_texture, + unsigned int sub_resource_idx, const struct wined3d_format *dst_format) { -#if defined(STAGING_CSMT) - void *dst_data = NULL, *src_data = NULL; - UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - const struct d3dfmt_converter_desc *conv; - struct wined3d_texture *ret = NULL; - struct wined3d_resource_desc desc; - struct wined3d_surface *dst; + unsigned int texture_level = sub_resource_idx % src_texture->level_count; + const struct wined3d_format *src_format = src_texture->resource.format; + struct wined3d_device *device = src_texture->resource.device; + const struct d3dfmt_converter_desc *conv = NULL; + const struct wined3d_gl_info *gl_info = NULL; + unsigned int src_row_pitch, src_slice_pitch; struct wined3d_context *context = NULL; - struct wined3d_device *device = source->resource.device; -#else /* STAGING_CSMT */ - struct wined3d_map_desc src_map, dst_map; - const struct d3dfmt_converter_desc *conv; - struct wined3d_texture *ret = NULL; + struct wined3d_texture *dst_texture; + struct wined3d_bo_address src_data; struct wined3d_resource_desc desc; - struct wined3d_surface *dst; -#endif /* STAGING_CSMT */ + DWORD map_binding; - conv = find_converter(source->resource.format->id, to_fmt); - if (!conv) + if (!(conv = find_converter(src_format->id, dst_format->id)) && (!device->d3d_initialized + || !is_identity_fixup(src_format->color_fixup) || src_format->convert + || !is_identity_fixup(dst_format->color_fixup) || dst_format->convert + || (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED))) { FIXME("Cannot find a conversion function from format %s to %s.\n", - debug_d3dformat(source->resource.format->id), debug_d3dformat(to_fmt)); + debug_d3dformat(src_format->id), debug_d3dformat(dst_format->id)); return NULL; } /* FIXME: Multisampled conversion? */ - wined3d_resource_get_desc(&source->resource, &desc); desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - desc.format = to_fmt; - desc.usage = 0; + desc.format = dst_format->id; + desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + desc.multisample_quality = 0; + desc.usage = WINED3DUSAGE_PRIVATE; desc.pool = WINED3D_POOL_SCRATCH; - if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1, + desc.width = wined3d_texture_get_level_width(src_texture, texture_level); + desc.height = wined3d_texture_get_level_height(src_texture, texture_level); + desc.depth = 1; + desc.size = 0; + if (FAILED(wined3d_texture_create(device, &desc, 1, 1, WINED3D_TEXTURE_CREATE_MAPPABLE | WINED3D_TEXTURE_CREATE_DISCARD, - NULL, NULL, &wined3d_null_parent_ops, &ret))) + NULL, NULL, &wined3d_null_parent_ops, &dst_texture))) { - ERR("Failed to create a destination surface for conversion.\n"); + ERR("Failed to create a destination texture for conversion.\n"); return NULL; } - dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); - -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&source->resource, &src_row_pitch, &src_slice_pitch); - wined3d_resource_get_pitch(&ret->resource, &dst_row_pitch, &dst_slice_pitch); if (device->d3d_initialized) - context = context_acquire(device, NULL); - - wined3d_resource_load_location(&source->resource, context, source->resource.map_binding); - src_data = wined3d_resource_get_map_ptr(&source->resource, context, WINED3D_MAP_READONLY); - if (!src_data) - goto error; - - if (!wined3d_resource_prepare_map_memory(&dst->resource, context)) - goto error; - dst_data = wined3d_resource_get_map_ptr(&dst->resource, context, 0); - if (!dst_data) - goto error; - - conv->convert(src_data, dst_data, src_row_pitch, dst_row_pitch, - source->resource.width, source->resource.height); - - wined3d_resource_release_map_ptr(&dst->resource, context); - wined3d_resource_release_map_ptr(&source->resource, context); - - if (context) - context_release(context); - - return ret; - -error: - ERR("Surface conversion failed.\n"); - - if (src_data) - wined3d_resource_release_map_ptr(&source->resource, context); - if (dst_data) - wined3d_resource_release_map_ptr(&ret->resource, context); - if (ret) - wined3d_texture_decref(ret); - if (context) - context_release(context); - return NULL; -#else /* STAGING_CSMT */ - memset(&src_map, 0, sizeof(src_map)); - memset(&dst_map, 0, sizeof(dst_map)); - - if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) { - ERR("Failed to lock the source surface.\n"); - wined3d_texture_decref(ret); - return NULL; - } - if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) - { - ERR("Failed to lock the destination surface.\n"); - wined3d_surface_unmap(source); - wined3d_texture_decref(ret); - return NULL; + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; } - conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, - source->resource.width, source->resource.height); + map_binding = src_texture->resource.map_binding; + if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding)) + ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_get_pitch(src_texture, texture_level, &src_row_pitch, &src_slice_pitch); + wined3d_texture_get_memory(src_texture, sub_resource_idx, &src_data, map_binding); - wined3d_surface_unmap(dst); - wined3d_surface_unmap(source); - - return ret; -#endif /* STAGING_CSMT */ -} - -static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height, - unsigned int bpp, UINT pitch, DWORD color) -{ - BYTE *first; - unsigned int x, y; - - /* Do first row */ - -#define COLORFILL_ROW(type) \ -do { \ - type *d = (type *)buf; \ - for (x = 0; x < width; ++x) \ - d[x] = (type)color; \ -} while(0) - - switch (bpp) + if (conv) { - case 1: - COLORFILL_ROW(BYTE); - break; + unsigned int dst_row_pitch, dst_slice_pitch; + struct wined3d_bo_address dst_data; + const BYTE *src; + BYTE *dst; - case 2: - COLORFILL_ROW(WORD); - break; + map_binding = dst_texture->resource.map_binding; + if (!wined3d_texture_load_location(dst_texture, 0, context, map_binding)) + ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_get_pitch(dst_texture, 0, &dst_row_pitch, &dst_slice_pitch); + wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding); - case 3: - { - BYTE *d = buf; - for (x = 0; x < width; ++x, d += 3) - { - d[0] = (color ) & 0xff; - d[1] = (color >> 8) & 0xff; - d[2] = (color >> 16) & 0xff; - } - break; - } - case 4: - COLORFILL_ROW(DWORD); - break; + src = context_map_bo_address(context, &src_data, + src_texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); + dst = context_map_bo_address(context, + &dst_data, dst_texture->sub_resources[0].size, GL_PIXEL_UNPACK_BUFFER, 0); - default: - FIXME("Color fill not implemented for bpp %u!\n", bpp * 8); - return WINED3DERR_NOTAVAILABLE; - } + conv->convert(src, dst, src_row_pitch, dst_row_pitch, desc.width, desc.height); -#undef COLORFILL_ROW - - /* Now copy first row. */ - first = buf; - for (y = 1; y < height; ++y) - { - buf += pitch; - memcpy(buf, first, width * bpp); - } - - return WINED3D_OK; -} - -HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) -{ -#if defined(STAGING_CSMT) - HRESULT hr; - TRACE("surface %p.\n", surface); - - hr = wined3d_resource_unmap(&surface->resource); - if (FAILED(hr)) - return hr; - - memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - - return hr; -#else /* STAGING_CSMT */ - TRACE("surface %p.\n", surface); - - if (!surface->resource.map_count) - { - WARN("Trying to unmap unmapped surface.\n"); - return WINEDDERR_NOTLOCKED; - } - --surface->resource.map_count; - - surface->surface_ops->surface_unmap(surface); - - return WINED3D_OK; -#endif /* STAGING_CSMT */ -} - -HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) -{ - const struct wined3d_format *format = surface->resource.format; - unsigned int fmt_flags = surface->container->resource.format_flags; -#if defined(STAGING_CSMT) - - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !surface_check_block_align(surface, box)) -#else /* STAGING_CSMT */ - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - BYTE *base_memory; - - TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", - surface, map_desc, debug_box(box), flags); - - if (surface->resource.map_count) - { - WARN("Surface is already mapped.\n"); - return WINED3DERR_INVALIDCALL; - } - - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !wined3d_texture_check_block_align(surface->container, surface->texture_level, box)) -#endif /* STAGING_CSMT */ - { - WARN("Map box %s is misaligned for %ux%u blocks.\n", - debug_box(box), format->block_width, format->block_height); - - if (surface->resource.pool == WINED3D_POOL_DEFAULT) - return WINED3DERR_INVALIDCALL; - } - -#if !defined(STAGING_CSMT) - ++surface->resource.map_count; - - if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - WARN("Trying to lock unlockable surface.\n"); - -#endif /* STAGING_CSMT */ - /* Performance optimization: Count how often a surface is mapped, if it is - * mapped regularly do not throw away the system memory copy. This avoids - * the need to download the surface from OpenGL all the time. The surface - * is still downloaded if the OpenGL texture is changed. Note that this - * only really makes sense for managed textures.*/ - if (!(surface->container->flags & WINED3D_TEXTURE_DYNAMIC_MAP) - && surface->resource.map_binding == WINED3D_LOCATION_SYSMEM) - { - if (++surface->lockCount > MAXLOCKCOUNT) - { - TRACE("Surface is mapped regularly, not freeing the system memory copy any more.\n"); - surface->container->flags |= WINED3D_TEXTURE_DYNAMIC_MAP; - } - } - -#if defined(STAGING_CSMT) - if (box) - { - surface->lockedRect.left = box->left; - surface->lockedRect.top = box->top; - surface->lockedRect.right = box->right; - surface->lockedRect.bottom = box->bottom; + wined3d_texture_invalidate_location(dst_texture, 0, ~map_binding); + context_unmap_bo_address(context, &dst_data, GL_PIXEL_UNPACK_BUFFER); + context_unmap_bo_address(context, &src_data, GL_PIXEL_UNPACK_BUFFER); } else { - surface->lockedRect.left = 0; - surface->lockedRect.top = 0; - surface->lockedRect.right = surface->resource.width; - surface->lockedRect.bottom = surface->resource.height; + RECT src_rect = {0, 0, desc.width, desc.height}; + POINT dst_point = {0, 0}; + + TRACE("Using upload conversion.\n"); + + wined3d_texture_prepare_texture(dst_texture, context, FALSE); + wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE); + wined3d_surface_upload_data(dst_texture->sub_resources[0].u.surface, gl_info, src_format, + &src_rect, src_row_pitch, &dst_point, FALSE, wined3d_const_bo_address(&src_data)); + + wined3d_texture_validate_location(dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, 0, ~WINED3D_LOCATION_TEXTURE_RGB); } - return wined3d_resource_map(&surface->resource, map_desc, box, flags); -} - -void wined3d_surface_getdc_cs(struct wined3d_surface *surface) -{ - HRESULT hr; - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context = NULL; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - /* Create a DIB section if there isn't a dc yet. */ - if (!surface->hDC) - { - if (FAILED(hr = surface_create_dib_section(surface))) - { - if (context) - context_release(context); - return; - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - || surface->resource.buffer)) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - } - - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_DIB); - wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); - if (context) context_release(context); -} -void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) -{ - if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - && surface->resource.map_binding != WINED3D_LOCATION_DIB)) - { - /* The game Salammbo modifies the surface contents without mapping the surface between - * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active - * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. - * Do not only copy the DIB to the map location, but also make sure the map location is - * copied back to the DIB in the next getdc call. - * - * The same consideration applies to user memory surfaces. */ - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context = NULL; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); - if (context) - context_release(context); - } + return dst_texture; } static void read_from_framebuffer(struct wined3d_surface *surface, struct wined3d_context *old_ctx, DWORD dst_location) { - struct wined3d_device *device = surface->resource.device; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; + struct wined3d_device *device = texture->resource.device; const struct wined3d_gl_info *gl_info; struct wined3d_context *context = old_ctx; struct wined3d_surface *restore_rt = NULL; unsigned int row_pitch, slice_pitch; + unsigned int width, height; BYTE *mem; BYTE *row, *top, *bottom; int i; BOOL srcIsUpsideDown; struct wined3d_bo_address data; - wined3d_resource_get_memory(&surface->resource, dst_location, &data); -#else /* STAGING_CSMT */ - surface_prepare_map_memory(surface); - if (flags & WINED3D_MAP_DISCARD) - { - TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", - wined3d_debug_location(surface->resource.map_binding)); - surface_validate_location(surface, surface->resource.map_binding); - } + wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); + + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != surface) + context = context_acquire(device, texture, sub_resource_idx); else - { - struct wined3d_context *context = NULL; - - if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) - WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); - - if (surface->resource.device->d3d_initialized) - context = context_acquire(surface->resource.device, NULL); - surface_load_location(surface, context, surface->resource.map_binding); - if (context) - context_release(context); - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) - surface_invalidate_location(surface, ~surface->resource.map_binding); - - switch (surface->resource.map_binding) - { - case WINED3D_LOCATION_SYSMEM: - base_memory = surface->resource.heap_memory; - break; - - case WINED3D_LOCATION_USER_MEMORY: - base_memory = surface->container->user_memory; - break; - - case WINED3D_LOCATION_DIB: - base_memory = surface->dib.bitmap_data; - break; - - case WINED3D_LOCATION_BUFFER: - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("map PBO"); - - context_release(context); - break; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); - base_memory = NULL; - } - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) - { - map_desc->row_pitch = surface->resource.width * format->byte_count; - map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; - } - else - { - wined3d_texture_get_pitch(surface->container, surface->texture_level, - &map_desc->row_pitch, &map_desc->slice_pitch); - } - - if (!box) - { - map_desc->data = base_memory; - surface->lockedRect.left = 0; - surface->lockedRect.top = 0; - surface->lockedRect.right = surface->resource.width; - surface->lockedRect.bottom = surface->resource.height; - } - else - { - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) - { - /* Compressed textures are block based, so calculate the offset of - * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = base_memory - + ((box->top / format->block_height) * map_desc->row_pitch) - + ((box->left / format->block_width) * format->block_byte_count); - } - else - { - map_desc->data = base_memory - + (map_desc->row_pitch * box->top) - + (box->left * format->byte_count); - } - surface->lockedRect.left = box->left; - surface->lockedRect.top = box->top; - surface->lockedRect.right = box->right; - surface->lockedRect.bottom = box->bottom; - } - - TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect)); - TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); - - return WINED3D_OK; -} - -static void read_from_framebuffer(struct wined3d_surface *surface, - struct wined3d_context *old_ctx, DWORD dst_location) -{ - struct wined3d_device *device = surface->resource.device; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context = old_ctx; - struct wined3d_surface *restore_rt = NULL; - unsigned int row_pitch, slice_pitch; - BYTE *mem; - BYTE *row, *top, *bottom; - int i; - BOOL srcIsUpsideDown; - struct wined3d_bo_address data; - - surface_get_memory(surface, &data, dst_location); -#endif /* STAGING_CSMT */ - - if (surface != old_ctx->current_rt) - { - restore_rt = old_ctx->current_rt; - context = context_acquire(device, surface); - } + restore_rt = NULL; context_apply_blit_state(context, device); gl_info = context->gl_info; @@ -3039,18 +1530,18 @@ static void read_from_framebuffer(struct wined3d_surface *surface, * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (wined3d_resource_is_offscreen(&surface->container->resource)) + if (wined3d_resource_is_offscreen(&texture->resource)) { /* Mapping the primary render target which is not on a swapchain. * Read from the back buffer. */ TRACE("Mapping offscreen render target.\n"); - gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer); + gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); srcIsUpsideDown = TRUE; } else { /* Onscreen surfaces are always part of a swapchain */ - GLenum buffer = surface_get_gl_buffer(surface); + GLenum buffer = wined3d_texture_get_gl_buffer(texture); TRACE("Mapping %#x buffer.\n", buffer); gl_info->gl_ops.gl.p_glReadBuffer(buffer); checkGLcall("glReadBuffer"); @@ -3063,20 +1554,17 @@ static void read_from_framebuffer(struct wined3d_surface *surface, checkGLcall("glBindBuffer"); } -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch); -#else /* STAGING_CSMT */ - wined3d_texture_get_pitch(surface->container, surface->texture_level, &row_pitch, &slice_pitch); -#endif /* STAGING_CSMT */ + wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch); /* Setup pixel store pack state -- to glReadPixels into the correct place */ - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / surface->resource.format->byte_count); + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / texture->resource.format->byte_count); checkGLcall("glPixelStorei"); - gl_info->gl_ops.gl.p_glReadPixels(0, 0, - surface->resource.width, surface->resource.height, - surface->resource.format->glFormat, - surface->resource.format->glType, data.addr); + width = wined3d_texture_get_level_width(texture, surface->texture_level); + height = wined3d_texture_get_level_height(texture, surface->texture_level); + gl_info->gl_ops.gl.p_glReadPixels(0, 0, width, height, + texture->resource.format->glFormat, + texture->resource.format->glType, data.addr); checkGLcall("glReadPixels"); /* Reset previous pixel store pack state */ @@ -3100,8 +1588,8 @@ static void read_from_framebuffer(struct wined3d_surface *surface, mem = data.addr; top = mem; - bottom = mem + row_pitch * (surface->resource.height - 1); - for (i = 0; i < surface->resource.height / 2; i++) + bottom = mem + row_pitch * (height - 1); + for (i = 0; i < height / 2; i++) { memcpy(row, top, row_pitch); memcpy(top, bottom, row_pitch); @@ -3134,109 +1622,57 @@ error: * switch to a different context and restore the original one before return. */ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx) { - struct wined3d_device *device = surface->resource.device; + struct wined3d_texture *texture = surface->container; + struct wined3d_device *device = texture->resource.device; const struct wined3d_gl_info *gl_info; struct wined3d_context *context = old_ctx; struct wined3d_surface *restore_rt = NULL; - if (old_ctx->current_rt != surface) - { - restore_rt = old_ctx->current_rt; - context = context_acquire(device, surface); - } + restore_rt = context_get_rt_surface(old_ctx); + if (restore_rt != surface) + context = context_acquire(device, texture, surface_get_sub_resource_idx(surface)); + else + restore_rt = NULL; gl_info = context->gl_info; device_invalidate_state(device, STATE_FRAMEBUFFER); - wined3d_texture_prepare_texture(surface->container, context, srgb); - wined3d_texture_bind_and_dirtify(surface->container, context, srgb); + wined3d_texture_prepare_texture(texture, context, srgb); + wined3d_texture_bind_and_dirtify(texture, context, srgb); TRACE("Reading back offscreen render target %p.\n", surface); - if (wined3d_resource_is_offscreen(&surface->container->resource)) - gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer); + if (wined3d_resource_is_offscreen(&texture->resource)) + gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); else - gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(surface)); + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(texture)); checkGLcall("glReadBuffer"); gl_info->gl_ops.gl.p_glCopyTexSubImage2D(surface->texture_target, surface->texture_level, - 0, 0, 0, 0, surface->resource.width, surface->resource.height); + 0, 0, 0, 0, wined3d_texture_get_level_width(texture, surface->texture_level), + wined3d_texture_get_level_height(texture, surface->texture_level)); checkGLcall("glCopyTexSubImage2D"); if (restore_rt) context_restore(context, restore_rt); } -static void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample) -{ - if (multisample) - { - DWORD samples; - - if (surface->rb_multisample) - return; - - /* TODO: Nvidia exposes their Coverage Sample Anti-Aliasing (CSAA) feature - * through type == MULTISAMPLE_XX and quality != 0. This could be mapped - * to GL_NV_framebuffer_multisample_coverage. - * - * AMD has a similar feature called Enhanced Quality Anti-Aliasing (EQAA), - * but it does not have an equivalent OpenGL extension. */ - - /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality levels - * as the count of advertised multisample types for the surface format. */ - if (surface->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) - { - const struct wined3d_format *format = surface->resource.format; - unsigned int i, count = 0; - - for (i = 0; i < sizeof(format->multisample_types) * 8; ++i) - { - if (format->multisample_types & 1u << i) - { - if (surface->resource.multisample_quality == count++) - break; - } - } - samples = i + 1; - } - else - { - samples = surface->resource.multisample_type; - } - - gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample); - gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - surface->resource.format->glInternal, surface->pow2Width, surface->pow2Height); - checkGLcall("glRenderbufferStorageMultisample()"); - TRACE("Created multisample rb %u.\n", surface->rb_multisample); - } - else - { - if (surface->rb_resolved) - return; - - gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_resolved); - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_resolved); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, surface->resource.format->glInternal, - surface->pow2Width, surface->pow2Height); - checkGLcall("glRenderbufferStorage()"); - TRACE("Created resolved rb %u.\n", surface->rb_resolved); - } -} - /* Does a direct frame buffer -> texture copy. Stretching is done with single * pixel copy calls. */ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) { - struct wined3d_device *device = dst_surface->resource.device; + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_device *device = dst_texture->resource.device; const struct wined3d_gl_info *gl_info; float xrel, yrel; struct wined3d_context *context; BOOL upsidedown = FALSE; RECT dst_rect = *dst_rect_in; + unsigned int src_height; /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag * glCopyTexSubImage is a bit picky about the parameters we pass to it @@ -3248,22 +1684,22 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc upsidedown = TRUE; } - context = context_acquire(device, src_surface); + context = context_acquire(device, src_texture, src_sub_resource_idx); gl_info = context->gl_info; context_apply_blit_state(context, device); - wined3d_texture_load(dst_surface->container, context, FALSE); + wined3d_texture_load(dst_texture, context, FALSE); /* Bind the target texture */ - context_bind_texture(context, dst_surface->container->target, dst_surface->container->texture_rgb.name); - if (wined3d_resource_is_offscreen(&src_surface->container->resource)) + context_bind_texture(context, dst_texture->target, dst_texture->texture_rgb.name); + if (wined3d_resource_is_offscreen(&src_texture->resource)) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer); + gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context)); } else { - gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(src_surface)); + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(src_texture)); } checkGLcall("glReadBuffer"); @@ -3272,7 +1708,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) { - FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n"); + FIXME_(d3d_perf)("Doing a pixel by pixel copy from the framebuffer to a texture.\n"); if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT) ERR("Texture filtering not supported in direct blit.\n"); @@ -3283,6 +1719,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc ERR("Texture filtering not supported in direct blit\n"); } + src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level); if (upsidedown && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps))) @@ -3290,13 +1727,13 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, dst_rect.left /*xoffset */, dst_rect.top /* y offset */, - src_rect->left, src_surface->resource.height - src_rect->bottom, + src_rect->left, src_height - src_rect->bottom, dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); } else { LONG row; - UINT yoffset = src_surface->resource.height - src_rect->top + dst_rect.top - 1; + UINT yoffset = src_height - src_rect->top + dst_rect.top - 1; /* I have to process this row by row to swap the image, * otherwise it would be upside down, so stretching in y direction * doesn't cost extra time @@ -3332,27 +1769,26 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -#else /* STAGING_CSMT */ - surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); - surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); -#endif /* STAGING_CSMT */ + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); } /* Uses the hardware to stretch and flip the image */ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface, const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter) { - struct wined3d_device *device = dst_surface->resource.device; + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_width, src_height, src_pow2_width, src_pow2_height; + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_device *device = dst_texture->resource.device; GLuint src, backup = 0; float left, right, top, bottom; /* Texture coordinates */ - UINT fbwidth = src_surface->resource.width; - UINT fbheight = src_surface->resource.height; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; GLenum drawBuffer = GL_BACK; + GLenum offscreen_buffer; GLenum texture_target; BOOL noBackBufferBackup; BOOL src_offscreen; @@ -3361,17 +1797,23 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st TRACE("Using hwstretch blit\n"); /* Activate the Proper context for reading from the source surface, set it up for blitting */ - context = context_acquire(device, src_surface); + context = context_acquire(device, src_texture, src_sub_resource_idx); gl_info = context->gl_info; context_apply_blit_state(context, device); - wined3d_texture_load(dst_surface->container, context, FALSE); + wined3d_texture_load(dst_texture, context, FALSE); - src_offscreen = wined3d_resource_is_offscreen(&src_surface->container->resource); + offscreen_buffer = context_get_offscreen_gl_buffer(context); + src_width = wined3d_texture_get_level_width(src_texture, src_surface->texture_level); + src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level); + src_pow2_width = wined3d_texture_get_level_pow2_width(src_texture, src_surface->texture_level); + src_pow2_height = wined3d_texture_get_level_pow2_height(src_texture, src_surface->texture_level); + + src_offscreen = wined3d_resource_is_offscreen(&src_texture->resource); noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !src_surface->container->texture_rgb.name) + if (!noBackBufferBackup && !src_texture->texture_rgb.name) { /* Get it a description */ - wined3d_texture_load(src_surface->container, context, FALSE); + wined3d_texture_load(src_texture, context, FALSE); } /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring. @@ -3382,7 +1824,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st /* Got more than one aux buffer? Use the 2nd aux buffer */ drawBuffer = GL_AUX1; } - else if ((!src_offscreen || device->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1) + else if ((!src_offscreen || offscreen_buffer == GL_BACK) && context->aux_buffers >= 1) { /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */ drawBuffer = GL_AUX0; @@ -3401,16 +1843,12 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st * we are reading from the back buffer, the backup can be used as source texture */ texture_target = src_surface->texture_target; - context_bind_texture(context, texture_target, src_surface->container->texture_rgb.name); + context_bind_texture(context, texture_target, src_texture->texture_rgb.name); gl_info->gl_ops.gl.p_glEnable(texture_target); checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ -#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&src_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); -#else /* STAGING_CSMT */ - src_surface->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; -#endif /* STAGING_CSMT */ + surface_get_sub_resource(src_surface)->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; } /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag @@ -3427,15 +1865,15 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer); + gl_info->gl_ops.gl.p_glReadBuffer(offscreen_buffer); } else { - gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(src_surface)); + gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(src_texture)); } /* TODO: Only back up the part that will be overwritten */ - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, 0, 0, 0, 0, fbwidth, fbheight); + gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, 0, 0, 0, 0, src_width, src_height); checkGLcall("glCopyTexSubImage2D"); @@ -3446,10 +1884,9 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); checkGLcall("glTexParameteri"); - if (!src_surface->container->swapchain - || src_surface->container == src_surface->container->swapchain->back_buffers[0]) + if (!src_texture->swapchain || src_texture == src_texture->swapchain->back_buffers[0]) { - src = backup ? backup : src_surface->container->texture_rgb.name; + src = backup ? backup : src_texture->texture_rgb.name; } else { @@ -3460,13 +1897,13 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glGenTextures(1, &src)"); context_bind_texture(context, GL_TEXTURE_2D, src); - /* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch - * out for power of 2 sizes - */ - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_surface->pow2Width, - src_surface->pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + /* TODO: Only copy the part that will be read. Use src_rect->left, + * src_rect->bottom as origin, but with the width watch out for power + * of 2 sizes. */ + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_pow2_width, + src_pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); checkGLcall("glTexImage2D"); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, fbwidth, fbheight); + gl_info->gl_ops.gl.p_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, src_width, src_height); gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri"); @@ -3490,21 +1927,21 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st if (!upsidedown) { - top = src_surface->resource.height - src_rect->top; - bottom = src_surface->resource.height - src_rect->bottom; + top = src_height - src_rect->top; + bottom = src_height - src_rect->bottom; } else { - top = src_surface->resource.height - src_rect->bottom; - bottom = src_surface->resource.height - src_rect->top; + top = src_height - src_rect->bottom; + bottom = src_height - src_rect->top; } - if (src_surface->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS) + if (src_texture->flags & WINED3D_TEXTURE_NORMALIZED_COORDS) { - left /= src_surface->pow2Width; - right /= src_surface->pow2Width; - top /= src_surface->pow2Height; - bottom /= src_surface->pow2Height; + left /= src_pow2_width; + right /= src_pow2_width; + top /= src_pow2_height; + bottom /= src_pow2_height; } /* draw the source texture stretched and upside down. The correct surface is bound already */ @@ -3541,7 +1978,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st } /* Now read the stretched and upside down image into the destination texture */ - context_bind_texture(context, texture_target, dst_surface->container->texture_rgb.name); + context_bind_texture(context, texture_target, dst_texture->texture_rgb.name); gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, dst_rect.left, dst_rect.top, /* xoffset, yoffset */ @@ -3570,33 +2007,33 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st gl_info->gl_ops.gl.p_glEnable(src_surface->texture_target); texture_target = src_surface->texture_target; } - context_bind_texture(context, src_surface->texture_target, src_surface->container->texture_rgb.name); + context_bind_texture(context, src_surface->texture_target, src_texture->texture_rgb.name); } gl_info->gl_ops.gl.p_glBegin(GL_QUADS); /* top left */ gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(0, fbheight); + gl_info->gl_ops.gl.p_glVertex2i(0, src_height); /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, (float)fbheight / (float)src_surface->pow2Height); + gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, (float)src_height / (float)src_pow2_height); gl_info->gl_ops.gl.p_glVertex2i(0, 0); /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, - (float)fbheight / (float)src_surface->pow2Height); - gl_info->gl_ops.gl.p_glVertex2i(fbwidth, 0); + gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, + (float)src_height / (float)src_pow2_height); + gl_info->gl_ops.gl.p_glVertex2i(src_width, 0); /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(fbwidth, fbheight); + gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, 0.0f); + gl_info->gl_ops.gl.p_glVertex2i(src_width, src_height); gl_info->gl_ops.gl.p_glEnd(); } gl_info->gl_ops.gl.p_glDisable(texture_target); checkGLcall("glDisable(texture_target)"); /* Cleanup */ - if (src != src_surface->container->texture_rgb.name && src != backup) + if (src != src_texture->texture_rgb.name && src != backup) { gl_info->gl_ops.gl.p_glDeleteTextures(1, &src); checkGLcall("glDeleteTextures(1, &src)"); @@ -3607,19 +2044,6 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glDeleteTextures(1, &backup)"); } -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); - - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -#else /* STAGING_CSMT */ if (wined3d_settings.strict_draw_ordering) gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ @@ -3627,9 +2051,8 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ - surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); - surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); -#endif /* STAGING_CSMT */ + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); } /* Front buffer coordinates are always full screen coordinates, but our GL @@ -3638,213 +2061,64 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st * origin, while D3D has a top-left origin. */ void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) { + struct wined3d_texture *texture = surface->container; + POINT offset = {0, 0}; UINT drawable_height; + RECT windowsize; - if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) + if (!texture->swapchain) + return; + + if (texture == texture->swapchain->front_buffer) { - POINT offset = {0, 0}; - RECT windowsize; - ScreenToClient(window, &offset); OffsetRect(rect, offset.x, offset.y); + } - GetClientRect(window, &windowsize); - drawable_height = windowsize.bottom - windowsize.top; - } - else - { - drawable_height = surface->resource.height; - } + GetClientRect(window, &windowsize); + drawable_height = windowsize.bottom - windowsize.top; rect->top = drawable_height - rect->top; rect->bottom = drawable_height - rect->bottom; } -/* Context activation is done by the caller. */ -static void surface_blt_to_drawable(const struct wined3d_device *device, - struct wined3d_context *old_ctx, - enum wined3d_texture_filter_type filter, BOOL alpha_test, - struct wined3d_surface *src_surface, const RECT *src_rect_in, - struct wined3d_surface *dst_surface, const RECT *dst_rect_in) -{ - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context = old_ctx; - struct wined3d_surface *restore_rt = NULL; - RECT src_rect, dst_rect; - - src_rect = *src_rect_in; - dst_rect = *dst_rect_in; - - - if (old_ctx->current_rt != dst_surface) - { - restore_rt = old_ctx->current_rt; - context = context_acquire(device, dst_surface); - } - - gl_info = context->gl_info; - -#if defined(STAGING_CSMT) - /* Make sure the surface is up-to-date. This should probably use - * wined3d_resource_load_location() and worry about the destination - * surface too, unless we're overwriting it completely. */ -#else /* STAGING_CSMT */ - /* Make sure the surface is up-to-date. This should probably use - * surface_load_location() and worry about the destination surface too, - * unless we're overwriting it completely. */ -#endif /* STAGING_CSMT */ - wined3d_texture_load(src_surface->container, context, FALSE); - - /* Activate the destination context, set it up for blitting */ - context_apply_blit_state(context, device); - - if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) - surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect); - - device->blitter->set_shader(device->blit_priv, context, src_surface, NULL); - - if (alpha_test) - { - gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); - checkGLcall("glEnable(GL_ALPHA_TEST)"); - - /* For P8 surfaces, the alpha component contains the palette index. - * Which means that the colorkey is one of the palette entries. In - * other cases pixels that should be masked away have alpha set to 0. */ - if (src_surface->resource.format->id == WINED3DFMT_P8_UINT) - gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, - (float)src_surface->container->async.src_blt_color_key.color_space_low_value / 255.0f); - else - gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f); - checkGLcall("glAlphaFunc"); - } - else - { - gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - checkGLcall("glDisable(GL_ALPHA_TEST)"); - } - - draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter); - - if (alpha_test) - { - gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - checkGLcall("glDisable(GL_ALPHA_TEST)"); - } - - /* Leave the opengl state valid for blitting */ - device->blitter->unset_shader(context->gl_info); - -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering -#else /* STAGING_CSMT */ - if (wined3d_settings.strict_draw_ordering -#endif /* STAGING_CSMT */ - || (dst_surface->container->swapchain - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - if (restore_rt) - context_restore(context, restore_rt); -} - -HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color) -{ - struct wined3d_resource *resource = &s->container->resource; - struct wined3d_device *device = resource->device; -#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view view; - struct wined3d_texture *texture = s->container; -#else /* STAGING_CSMT */ - struct wined3d_rendertarget_view_desc view_desc; - struct wined3d_rendertarget_view *view; -#endif /* STAGING_CSMT */ - const struct blit_shader *blitter; - HRESULT hr; - - if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, - WINED3D_BLIT_OP_COLOR_FILL, NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format))) - { - FIXME("No blitter is capable of performing the requested color fill operation.\n"); - return WINED3DERR_INVALIDCALL; - } - -#if defined(STAGING_CSMT) - /* Can't incref / decref the resource here. This is executed inside the worker - * thread. Playing with the refcount here makes the worker thread visible to - * the client lib. Problems occur when the worker thread happens to hold the - * last reference and the resource destruction callbacks are called from the - * wrong thread. */ - view.resource = &texture->resource; - view.parent = NULL; - view.parent_ops = &wined3d_null_parent_ops; - view.format = s->resource.format; - view.buffer_offset = 0; - view.width = s->resource.width; - view.height = s->resource.height; - view.depth = 1; - view.sub_resource_idx = s->texture_layer * texture->level_count + s->texture_level; - - hr = blitter->color_fill(device, &view, rect, color); -#else /* STAGING_CSMT */ - view_desc.format_id = resource->format->id; - view_desc.u.texture.level_idx = s->texture_level; - view_desc.u.texture.layer_idx = s->texture_layer; - view_desc.u.texture.layer_count = 1; - if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, - resource, NULL, &wined3d_null_parent_ops, &view))) - { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - return hr; - } - - hr = blitter->color_fill(device, view, rect, color); - wined3d_rendertarget_view_decref(view); -#endif /* STAGING_CSMT */ - - return hr; -} - static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect, struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { - struct wined3d_device *device = dst_surface->resource.device; -#if defined(STAGING_CSMT) - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[0]); -#else /* STAGING_CSMT */ + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_device *device = dst_texture->resource.device; const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); struct wined3d_swapchain *src_swapchain, *dst_swapchain; -#endif /* STAGING_CSMT */ + struct wined3d_texture *src_texture; TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); /* Get the swapchain. One of the surfaces has to be a primary surface */ - if (dst_surface->resource.pool == WINED3D_POOL_SYSTEM_MEM) + if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM) { WARN("Destination is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - dst_swapchain = dst_surface->container->swapchain; + dst_swapchain = dst_texture->swapchain; if (src_surface) { - if (src_surface->resource.pool == WINED3D_POOL_SYSTEM_MEM) + src_texture = src_surface->container; + if (src_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM) { WARN("Src is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - src_swapchain = src_surface->container->swapchain; + src_swapchain = src_texture->swapchain; } else { + src_texture = NULL; src_swapchain = NULL; } @@ -3889,12 +2163,13 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE if ((src_swapchain || src_surface == rt) && !dst_swapchain) { + unsigned int src_width, src_height; /* Blit from render target to texture */ BOOL stretchx; /* P8 read back is not implemented */ - if (src_surface->resource.format->id == WINED3DFMT_P8_UINT - || dst_surface->resource.format->id == WINED3DFMT_P8_UINT) + if (src_texture->resource.format->id == WINED3DFMT_P8_UINT + || dst_texture->resource.format->id == WINED3DFMT_P8_UINT) { TRACE("P8 read back not supported by frame buffer to texture blit\n"); return WINED3DERR_INVALIDCALL; @@ -3922,8 +2197,10 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE * back buffer. This is slower than reading line per line, thus not used for flipping * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied * pixel by pixel. */ - if (!stretchx || dst_rect->right - dst_rect->left > src_surface->resource.width - || dst_rect->bottom - dst_rect->top > src_surface->resource.height) + src_width = wined3d_texture_get_level_width(src_texture, src_surface->texture_level); + src_height = wined3d_texture_get_level_height(src_texture, src_surface->texture_level); + if (!stretchx || dst_rect->right - dst_rect->left > src_width + || dst_rect->bottom - dst_rect->top > src_height) { TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n"); fb_copy_to_texture_direct(dst_surface, src_surface, src_rect, dst_rect, filter); @@ -3934,8 +2211,6 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter); } - surface_evict_sysmem(dst_surface); - return WINED3D_OK; } @@ -3945,505 +2220,129 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE } /* Context activation is done by the caller. */ -static void surface_depth_blt(const struct wined3d_surface *surface, struct wined3d_context *context, - GLuint texture, GLint x, GLint y, GLsizei w, GLsizei h, GLenum target) -{ - struct wined3d_device *device = surface->resource.device; - const struct wined3d_gl_info *gl_info = context->gl_info; - GLint compare_mode = GL_NONE; - struct blt_info info; - GLint old_binding = 0; - RECT rect; - - gl_info->gl_ops.gl.p_glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT); - - gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); - gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); - gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST); - gl_info->gl_ops.gl.p_glDepthFunc(GL_ALWAYS); - gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE); - gl_info->gl_ops.gl.p_glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_info->gl_ops.gl.p_glViewport(x, y, w, h); - gl_info->gl_ops.gl.p_glDepthRange(0.0, 1.0); - - SetRect(&rect, 0, h, w, 0); - surface_get_blt_info(target, &rect, surface->pow2Width, surface->pow2Height, &info); - context_active_texture(context, context->gl_info, 0); - gl_info->gl_ops.gl.p_glGetIntegerv(info.binding, &old_binding); - gl_info->gl_ops.gl.p_glBindTexture(info.bind_target, texture); - if (gl_info->supported[ARB_SHADOW]) - { - gl_info->gl_ops.gl.p_glGetTexParameteriv(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, &compare_mode); - if (compare_mode != GL_NONE) - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - } - - device->shader_backend->shader_select_depth_blt(device->shader_priv, - gl_info, info.tex_type, &surface->ds_current_size); - - gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]); - gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]); - gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]); - gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]); - gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f); - gl_info->gl_ops.gl.p_glEnd(); - - if (compare_mode != GL_NONE) - gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, compare_mode); - gl_info->gl_ops.gl.p_glBindTexture(info.bind_target, old_binding); - - gl_info->gl_ops.gl.p_glPopAttrib(); - - device->shader_backend->shader_deselect_depth_blt(device->shader_priv, gl_info); -} - -void surface_modify_ds_location(struct wined3d_surface *surface, - DWORD location, UINT w, UINT h) -{ - TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); - -#if defined(STAGING_CSMT) - if (((surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) - || (!(surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) - && (location & WINED3D_LOCATION_TEXTURE_RGB))) - wined3d_texture_set_dirty(surface->container); - - surface->ds_current_size.cx = w; - surface->ds_current_size.cy = h; - surface->resource.locations = location; -#else /* STAGING_CSMT */ - if (((surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) - || (!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && (location & WINED3D_LOCATION_TEXTURE_RGB))) - wined3d_texture_set_dirty(surface->container); - - surface->ds_current_size.cx = w; - surface->ds_current_size.cy = h; - surface->locations = location; -#endif /* STAGING_CSMT */ -} - -/* Context activation is done by the caller. */ -void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_device *device = surface->resource.device; - GLsizei w, h; - - TRACE("surface %p, context %p, new location %#x.\n", surface, context, location); - - /* TODO: Make this work for modes other than FBO */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - -#if defined(STAGING_CSMT) - if (!(surface->resource.locations & location)) -#else /* STAGING_CSMT */ - if (!(surface->locations & location)) -#endif /* STAGING_CSMT */ - { - w = surface->ds_current_size.cx; - h = surface->ds_current_size.cy; - surface->ds_current_size.cx = 0; - surface->ds_current_size.cy = 0; - } - else - { - w = surface->resource.width; - h = surface->resource.height; - } - - if (surface->ds_current_size.cx == surface->resource.width - && surface->ds_current_size.cy == surface->resource.height) - { - TRACE("Location (%#x) is already up to date.\n", location); - return; - } - - if (surface->current_renderbuffer) - { - FIXME("Not supported with fixed up depth stencil.\n"); - return; - } - - wined3d_surface_prepare(surface, context, location); -#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Surface was discarded, no need copy data.\n"); - surface->resource.locations &= ~WINED3D_LOCATION_DISCARDED; - surface->resource.locations |= location; - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; - return; - } - - if (!surface->resource.locations) - { - FIXME("No up to date depth stencil location.\n"); - surface->resource.locations |= location; -#else /* STAGING_CSMT */ - if (surface->locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Surface was discarded, no need copy data.\n"); - surface->locations &= ~WINED3D_LOCATION_DISCARDED; - surface->locations |= location; - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; - return; - } - - if (!surface->locations) - { - FIXME("No up to date depth stencil location.\n"); - surface->locations |= location; -#endif /* STAGING_CSMT */ - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; - return; - } - - if (location == WINED3D_LOCATION_TEXTURE_RGB) - { - GLint old_binding = 0; - GLenum bind_target; - - /* The render target is allowed to be smaller than the depth/stencil - * buffer, so the onscreen depth/stencil buffer is potentially smaller - * than the offscreen surface. Don't overwrite the offscreen surface - * with undefined data. */ - w = min(w, context->swapchain->desc.backbuffer_width); - h = min(h, context->swapchain->desc.backbuffer_height); - - TRACE("Copying onscreen depth buffer to depth texture.\n"); - - if (!device->depth_blt_texture) - gl_info->gl_ops.gl.p_glGenTextures(1, &device->depth_blt_texture); - - /* Note that we use depth_blt here as well, rather than glCopyTexImage2D - * directly on the FBO texture. That's because we need to flip. */ - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - surface_from_resource(wined3d_texture_get_sub_resource(context->swapchain->front_buffer, 0)), - NULL, WINED3D_LOCATION_DRAWABLE); - if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); - bind_target = GL_TEXTURE_RECTANGLE_ARB; - } - else - { - gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); - bind_target = GL_TEXTURE_2D; - } - gl_info->gl_ops.gl.p_glBindTexture(bind_target, device->depth_blt_texture); - /* We use GL_DEPTH_COMPONENT instead of the surface's specific - * internal format, because the internal format might include stencil - * data. In principle we should copy stencil data as well, but unless - * the driver supports stencil export it's hard to do, and doesn't - * seem to be needed in practice. If the hardware doesn't support - * writing stencil data, the glCopyTexImage2D() call might trigger - * software fallbacks. */ - gl_info->gl_ops.gl.p_glCopyTexImage2D(bind_target, 0, GL_DEPTH_COMPONENT, 0, 0, w, h, 0); - gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glBindTexture(bind_target, old_binding); - - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - NULL, surface, WINED3D_LOCATION_TEXTURE_RGB); - context_set_draw_buffer(context, GL_NONE); - - /* Do the actual blit */ - surface_depth_blt(surface, context, device->depth_blt_texture, 0, 0, w, h, bind_target); - checkGLcall("depth_blt"); - - context_invalidate_state(context, STATE_FRAMEBUFFER); - -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) -#else /* STAGING_CSMT */ - if (wined3d_settings.strict_draw_ordering) -#endif /* STAGING_CSMT */ - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else if (location == WINED3D_LOCATION_DRAWABLE) - { - TRACE("Copying depth texture to onscreen depth buffer.\n"); - - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, - surface_from_resource(wined3d_texture_get_sub_resource(context->swapchain->front_buffer, 0)), - NULL, WINED3D_LOCATION_DRAWABLE); - surface_depth_blt(surface, context, surface->container->texture_rgb.name, - 0, surface->pow2Height - h, w, h, surface->texture_target); - checkGLcall("depth_blt"); - - context_invalidate_state(context, STATE_FRAMEBUFFER); - -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) -#else /* STAGING_CSMT */ - if (wined3d_settings.strict_draw_ordering) -#endif /* STAGING_CSMT */ - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else - { - ERR("Invalid location (%#x) specified.\n", location); - } - -#if defined(STAGING_CSMT) - surface->resource.locations |= location; - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; -} - -/* Context activation is done by the caller. */ -static void surface_load_sysmem(struct wined3d_surface *surface, +static BOOL surface_load_sysmem(struct wined3d_surface *surface, struct wined3d_context *context, DWORD dst_location) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture *texture = surface->container; + struct wined3d_texture_sub_resource *sub_resource; - if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + sub_resource = &texture->sub_resources[sub_resource_idx]; + wined3d_texture_prepare_location(texture, sub_resource_idx, context, dst_location); + + if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) + wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); /* Download the surface to system memory. */ - if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { - wined3d_texture_bind_and_dirtify(surface->container, context, - !(surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB)); + wined3d_texture_bind_and_dirtify(texture, context, + !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)); surface_download_data(surface, gl_info, dst_location); + ++texture->download_count; - return; + return TRUE; } - if (surface->resource.locations & WINED3D_LOCATION_DRAWABLE) + if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { read_from_framebuffer(surface, context, dst_location); - return; + return TRUE; } FIXME("Can't load surface %p with location flags %s into sysmem.\n", - surface, wined3d_debug_location(surface->resource.locations)); -#else /* STAGING_CSMT */ - surface->locations |= location; - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; -} - -void surface_validate_location(struct wined3d_surface *surface, DWORD location) -{ - TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); - - surface->locations |= location; -} - -void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) -{ - TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); - - if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - wined3d_texture_set_dirty(surface->container); - surface->locations &= ~location; - - if (!surface->locations) - ERR("Surface %p does not have any up to date location.\n", surface); -} - -static DWORD resource_access_from_location(DWORD location) -{ - switch (location) - { - case WINED3D_LOCATION_SYSMEM: - case WINED3D_LOCATION_USER_MEMORY: - case WINED3D_LOCATION_DIB: - case WINED3D_LOCATION_BUFFER: - return WINED3D_RESOURCE_ACCESS_CPU; - - case WINED3D_LOCATION_DRAWABLE: - case WINED3D_LOCATION_TEXTURE_SRGB: - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_RB_MULTISAMPLE: - case WINED3D_LOCATION_RB_RESOLVED: - return WINED3D_RESOURCE_ACCESS_GPU; - - default: - FIXME("Unhandled location %#x.\n", location); - return 0; - } -} - -static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) -{ - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - struct wined3d_bo_address dst, src; - UINT size = surface->resource.size; - - surface_get_memory(surface, &dst, location); - surface_get_memory(surface, &src, surface->locations); - - if (dst.buffer_object) - { - context = context_acquire(device, NULL); - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); - GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Upload PBO"); - context_release(context); - return; - } - if (src.buffer_object) - { - context = context_acquire(device, NULL); - gl_info = context->gl_info; - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); - GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("Download PBO"); - context_release(context); - return; - } - memcpy(dst.addr, src.addr, size); + surface, wined3d_debug_location(sub_resource->locations)); + return FALSE; } /* Context activation is done by the caller. */ -static void surface_load_sysmem(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD dst_location) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (surface->locations & surface_simple_locations) - { - surface_copy_simple_location(surface, dst_location); - return; - } - - if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) - surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); - - /* Download the surface to system memory. */ - if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - wined3d_texture_bind_and_dirtify(surface->container, context, - !(surface->locations & WINED3D_LOCATION_TEXTURE_RGB)); - surface_download_data(surface, gl_info, dst_location); - - return; - } - - if (surface->locations & WINED3D_LOCATION_DRAWABLE) - { - read_from_framebuffer(surface, context, dst_location); - return; - } - - FIXME("Can't load surface %p with location flags %s into sysmem.\n", - surface, wined3d_debug_location(surface->locations)); -#endif /* STAGING_CSMT */ -} - -/* Context activation is done by the caller. */ -static HRESULT surface_load_drawable(struct wined3d_surface *surface, +static BOOL surface_load_drawable(struct wined3d_surface *surface, struct wined3d_context *context) { + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); + struct wined3d_texture *texture = surface->container; + struct wined3d_surface *restore_rt = NULL; + struct wined3d_device *device; RECT r; -#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) + if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { - TRACE("Surface was discarded, nothing to do.\n"); - return WINED3D_OK; + DWORD current = texture->sub_resources[sub_resource_idx].locations; + FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", + wined3d_debug_location(current)); + return FALSE; } -#endif /* STAGING_CSMT */ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && wined3d_resource_is_offscreen(&surface->container->resource)) + && wined3d_resource_is_offscreen(&texture->resource)) { ERR("Trying to load offscreen surface into WINED3D_LOCATION_DRAWABLE.\n"); - return WINED3DERR_INVALIDCALL; + return FALSE; } - surface_get_rect(surface, NULL, &r); -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); -#else /* STAGING_CSMT */ - surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); -#endif /* STAGING_CSMT */ - surface_blt_to_drawable(surface->resource.device, context, - WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r); + device = texture->resource.device; + restore_rt = context_get_rt_surface(context); + if (restore_rt != surface) + context = context_acquire(device, texture, sub_resource_idx); + else + restore_rt = NULL; - return WINED3D_OK; + SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, surface->texture_level), + wined3d_texture_get_level_height(texture, surface->texture_level)); + wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, + surface, WINED3D_LOCATION_TEXTURE_RGB, &r, + surface, WINED3D_LOCATION_DRAWABLE, &r, + NULL, WINED3D_TEXF_POINT); + + if (restore_rt) + context_restore(context, restore_rt); + + return TRUE; } -static HRESULT surface_load_texture(struct wined3d_surface *surface, +static BOOL surface_load_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) { -#if defined(STAGING_CSMT) - unsigned int width, src_row_pitch, src_slice_pitch, dst_pitch; -#else /* STAGING_CSMT */ - unsigned int width, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; -#endif /* STAGING_CSMT */ - const RECT src_rect = {0, 0, surface->resource.width, surface->resource.height}; + unsigned int width, height, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface); const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_device *device = surface->resource.device; - const struct wined3d_color_key_conversion *conversion; struct wined3d_texture *texture = surface->container; + struct wined3d_device *device = texture->resource.device; + const struct wined3d_color_key_conversion *conversion; + struct wined3d_texture_sub_resource *sub_resource; struct wined3d_bo_address data; + BYTE *src_mem, *dst_mem = NULL; struct wined3d_format format; POINT dst_point = {0, 0}; - BYTE *mem = NULL; -#if defined(STAGING_CSMT) - const DWORD simple_locations = - WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY - | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; + RECT src_rect; + BOOL depth; - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Surface was discarded, nothing to do.\n"); - wined3d_texture_prepare_texture(texture, context, srgb); - return WINED3D_OK; - } + depth = texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL; + sub_resource = surface_get_sub_resource(surface); - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + if (!depth && wined3d_settings.offscreen_rendering_mode != ORM_FBO && wined3d_resource_is_offscreen(&texture->resource) - && (surface->resource.locations & WINED3D_LOCATION_DRAWABLE)) + && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) { surface_load_fb_texture(surface, srgb, context); - return WINED3D_OK; + return TRUE; } - if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) -#else /* STAGING_CSMT */ + width = wined3d_texture_get_level_width(texture, surface->texture_level); + height = wined3d_texture_get_level_height(texture, surface->texture_level); + SetRect(&src_rect, 0, 0, width, height); - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && wined3d_resource_is_offscreen(&texture->resource) - && (surface->locations & WINED3D_LOCATION_DRAWABLE)) - { - surface_load_fb_texture(surface, srgb, context); - - return WINED3D_OK; - } - - if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) -#endif /* STAGING_CSMT */ - && (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) - && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) + if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) + && (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) + && fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, + texture->resource.usage, texture->resource.pool, + texture->resource.format, WINED3D_LOCATION_TEXTURE_RGB, + texture->resource.usage, texture->resource.pool, + texture->resource.format, WINED3D_LOCATION_TEXTURE_SRGB)) { if (srgb) surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB, @@ -4452,436 +2351,298 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect); - return WINED3D_OK; + return TRUE; } -#if defined(STAGING_CSMT) - if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) - && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) - && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) + if (!depth && sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) + && (!srgb || (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))) { - DWORD src_location = surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED ? -#else /* STAGING_CSMT */ - if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) - && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) - && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) - { - DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ? -#endif /* STAGING_CSMT */ + DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ? WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - RECT rect = {0, 0, surface->resource.width, surface->resource.height}; - surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location, - &rect, surface, dst_location, &rect); + if (fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, + texture->resource.usage, texture->resource.pool, texture->resource.format, src_location, + texture->resource.usage, texture->resource.pool, texture->resource.format, dst_location)) + surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location, + &src_rect, surface, dst_location, &src_rect); - return WINED3D_OK; + return TRUE; } /* Upload from system memory */ if (srgb) { -#if defined(STAGING_CSMT) - if ((surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) + if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture->resource.map_binding)) == WINED3D_LOCATION_TEXTURE_RGB) { - /* Performance warning... */ - FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + FIXME_(d3d_perf)("Downloading RGB surface %p to reload it as sRGB.\n", surface); + wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } } else { - if ((surface->resource.locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding)) + if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture->resource.map_binding)) == WINED3D_LOCATION_TEXTURE_SRGB) { - /* Performance warning... */ - FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + FIXME_(d3d_perf)("Downloading sRGB surface %p to reload it as RGB.\n", surface); + wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } } - if (!(surface->resource.locations & simple_locations)) + if (!(sub_resource->locations & surface_simple_locations)) { WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); /* Lets hope we get it from somewhere... */ - wined3d_resource_prepare_system_memory(&surface->resource); - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM); - } - - wined3d_texture_prepare_texture(texture, context, srgb); - wined3d_texture_bind_and_dirtify(texture, context, srgb); - wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch); -#else /* STAGING_CSMT */ - if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) - == WINED3D_LOCATION_TEXTURE_RGB) - { - /* Performance warning... */ - FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); - surface_prepare_map_memory(surface); - surface_load_location(surface, context, surface->resource.map_binding); - } - } - else - { - if ((surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding)) - == WINED3D_LOCATION_TEXTURE_SRGB) - { - /* Performance warning... */ - FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); - surface_prepare_map_memory(surface); - surface_load_location(surface, context, surface->resource.map_binding); - } - } - - if (!(surface->locations & surface_simple_locations)) - { - WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); - /* Lets hope we get it from somewhere... */ - surface_prepare_system_memory(surface); - surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); + wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); } wined3d_texture_prepare_texture(texture, context, srgb); wined3d_texture_bind_and_dirtify(texture, context, srgb); wined3d_texture_get_pitch(texture, surface->texture_level, &src_row_pitch, &src_slice_pitch); -#endif /* STAGING_CSMT */ - - width = surface->resource.width; format = *texture->resource.format; if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) - format = *wined3d_get_format(gl_info, conversion->dst_format); + format = *wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ -#if defined(STAGING_CSMT) - if ((format.convert || conversion) && surface->resource.buffer) +#if !defined(STAGING_CSMT) + if ((format.convert || conversion) && texture->sub_resources[sub_resource_idx].buffer_object) #else /* STAGING_CSMT */ - if ((format.convert || conversion) && surface->pbo) + if ((format.convert || conversion) && texture->sub_resources[sub_resource_idx].buffer) #endif /* STAGING_CSMT */ { TRACE("Removing the pbo attached to surface %p.\n", surface); - if (surface->flags & SFLAG_DIBSECTION) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - else - surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; - -#if defined(STAGING_CSMT) - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_free_bo(&surface->resource); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); + wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); + wined3d_texture_set_map_binding(texture, WINED3D_LOCATION_SYSMEM); } - wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations); if (format.convert) { /* This code is entered for texture formats which need a fixup. */ - UINT height = surface->resource.height; - - format.byte_count = format.conv_byte_count; - dst_pitch = wined3d_format_calculate_pitch(&format, width); - - if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) - { - ERR("Out of memory (%u).\n", dst_pitch * height); - context_release(context); - return E_OUTOFMEMORY; - } - format.convert(data.addr, mem, src_row_pitch, src_slice_pitch, - dst_pitch, dst_pitch * height, width, height, 1); - src_row_pitch = dst_pitch; -#else /* STAGING_CSMT */ - surface_prepare_map_memory(surface); - surface_load_location(surface, context, surface->resource.map_binding); - surface_remove_pbo(surface, gl_info); - } - - surface_get_memory(surface, &data, surface->locations); - if (format.convert) - { - /* This code is entered for texture formats which need a fixup. */ - UINT height = surface->resource.height; - format.byte_count = format.conv_byte_count; wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch); - if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch))) + src_mem = context_map_bo_address(context, &data, src_slice_pitch, + GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY); + if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch))) { ERR("Out of memory (%u).\n", dst_slice_pitch); context_release(context); - return E_OUTOFMEMORY; + return FALSE; } - format.convert(data.addr, mem, src_row_pitch, src_slice_pitch, + format.convert(src_mem, dst_mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, width, height, 1); src_row_pitch = dst_row_pitch; -#endif /* STAGING_CSMT */ - data.addr = mem; + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + data.buffer_object = 0; + data.addr = dst_mem; } else if (conversion) { /* This code is only entered for color keying fixups */ struct wined3d_palette *palette = NULL; - UINT height = surface->resource.height; -#if defined(STAGING_CSMT) - dst_pitch = wined3d_format_calculate_pitch(&format, width); - dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); - - if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) - { - ERR("Out of memory (%u).\n", dst_pitch * height); - context_release(context); - return E_OUTOFMEMORY; - } - if (texture->swapchain && texture->swapchain->palette) - palette = texture->swapchain->palette; - conversion->convert(data.addr, src_row_pitch, mem, dst_pitch, - width, height, palette, &texture->async.gl_color_key); - src_row_pitch = dst_pitch; -#else /* STAGING_CSMT */ wined3d_format_calculate_pitch(&format, device->surface_alignment, width, height, &dst_row_pitch, &dst_slice_pitch); - if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch))) + src_mem = context_map_bo_address(context, &data, src_slice_pitch, + GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY); + if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch))) { ERR("Out of memory (%u).\n", dst_slice_pitch); context_release(context); - return E_OUTOFMEMORY; + return FALSE; } if (texture->swapchain && texture->swapchain->palette) palette = texture->swapchain->palette; - conversion->convert(data.addr, src_row_pitch, mem, dst_row_pitch, + conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch, width, height, palette, &texture->async.gl_color_key); src_row_pitch = dst_row_pitch; -#endif /* STAGING_CSMT */ - data.addr = mem; + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + data.buffer_object = 0; + data.addr = dst_mem; } wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); - HeapFree(GetProcessHeap(), 0, mem); + HeapFree(GetProcessHeap(), 0, dst_mem); - return WINED3D_OK; + return TRUE; } /* Context activation is done by the caller. */ -static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wined3d_context *context, +static BOOL surface_load_renderbuffer(struct wined3d_surface *surface, struct wined3d_context *context, DWORD dst_location) { - const RECT rect = {0, 0, surface->resource.width, surface->resource.height}; + struct wined3d_texture *texture = surface->container; + const RECT rect = {0, 0, + wined3d_texture_get_level_width(texture, surface->texture_level), + wined3d_texture_get_level_height(texture, surface->texture_level)}; + DWORD locations = surface_get_sub_resource(surface)->locations; DWORD src_location; -#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_RB_MULTISAMPLE) + if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + FIXME("Unimplemented copy from %s for depth/stencil buffers.\n", + wined3d_debug_location(locations)); + return FALSE; + } + + if (locations & WINED3D_LOCATION_RB_MULTISAMPLE) src_location = WINED3D_LOCATION_RB_MULTISAMPLE; - else if (surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED) + else if (locations & WINED3D_LOCATION_RB_RESOLVED) src_location = WINED3D_LOCATION_RB_RESOLVED; - else if (surface->resource.locations & WINED3D_LOCATION_TEXTURE_SRGB) -#else /* STAGING_CSMT */ - if (surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE) - src_location = WINED3D_LOCATION_RB_MULTISAMPLE; - else if (surface->locations & WINED3D_LOCATION_RB_RESOLVED) - src_location = WINED3D_LOCATION_RB_RESOLVED; - else if (surface->locations & WINED3D_LOCATION_TEXTURE_SRGB) -#endif /* STAGING_CSMT */ + else if (locations & WINED3D_LOCATION_TEXTURE_SRGB) src_location = WINED3D_LOCATION_TEXTURE_SRGB; else /* surface_blt_fbo will load the source location if necessary. */ src_location = WINED3D_LOCATION_TEXTURE_RGB; - surface_blt_fbo(surface->resource.device, context, WINED3D_TEXF_POINT, + surface_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, surface, src_location, &rect, surface, dst_location, &rect); + + return TRUE; } -#if defined(STAGING_CSMT) -/* Context activation is done by the caller. */ -static void wined3d_surface_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - struct wined3d_surface *surface = surface_from_resource(resource); -#else /* STAGING_CSMT */ /* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ -HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) +BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) { -#endif /* STAGING_CSMT */ - HRESULT hr; - TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); - if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) - { - if (location == WINED3D_LOCATION_TEXTURE_RGB -#if defined(STAGING_CSMT) - && surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) - { - surface_load_ds_location(surface, context, location); - return; - } - else if (location & surface->resource.locations - && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) - { - /* Already up to date, nothing to do. */ - return; - } - else - { - FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", - wined3d_debug_location(surface->resource.locations), wined3d_debug_location(location)); - return; - } - } - - if (!surface->resource.locations) - { - ERR("Surface %p does not have any up to date location.\n", surface); - return; -#else /* STAGING_CSMT */ - && surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) - { - surface_load_ds_location(surface, context, location); - return WINED3D_OK; - } - else if (location & surface->locations - && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) - { - /* Already up to date, nothing to do. */ - return WINED3D_OK; - } - else - { - FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", - wined3d_debug_location(surface->locations), wined3d_debug_location(location)); - return WINED3DERR_INVALIDCALL; - } - } - - if (surface->locations & location) - { - TRACE("Location already up to date.\n"); - return WINED3D_OK; - } - - if (WARN_ON(d3d_surface)) - { - DWORD required_access = resource_access_from_location(location); - if ((surface->resource.access_flags & required_access) != required_access) - WARN("Operation requires %#x access, but surface only has %#x.\n", - required_access, surface->resource.access_flags); - } - - if (!surface->locations) - { - ERR("Surface %p does not have any up to date location.\n", surface); - return WINED3DERR_INVALIDCALL; -#endif /* STAGING_CSMT */ - } - switch (location) { - case WINED3D_LOCATION_DIB: case WINED3D_LOCATION_USER_MEMORY: case WINED3D_LOCATION_SYSMEM: case WINED3D_LOCATION_BUFFER: - surface_load_sysmem(surface, context, location); - break; + return surface_load_sysmem(surface, context, location); case WINED3D_LOCATION_DRAWABLE: - if (FAILED(hr = surface_load_drawable(surface, context))) -#if defined(STAGING_CSMT) - return; -#else /* STAGING_CSMT */ - return hr; -#endif /* STAGING_CSMT */ - break; + return surface_load_drawable(surface, context); case WINED3D_LOCATION_RB_RESOLVED: case WINED3D_LOCATION_RB_MULTISAMPLE: - surface_load_renderbuffer(surface, context, location); - break; + return surface_load_renderbuffer(surface, context, location); case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_SRGB: - if (FAILED(hr = surface_load_texture(surface, context, - location == WINED3D_LOCATION_TEXTURE_SRGB))) -#if defined(STAGING_CSMT) - return; -#else /* STAGING_CSMT */ - return hr; -#endif /* STAGING_CSMT */ - break; + return surface_load_texture(surface, context, + location == WINED3D_LOCATION_TEXTURE_SRGB); default: ERR("Don't know how to handle location %#x.\n", location); - break; + return FALSE; } - -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&surface->resource, location); - - if (location != WINED3D_LOCATION_SYSMEM && (surface->resource.locations & WINED3D_LOCATION_SYSMEM)) - surface_evict_sysmem(surface); - - return; -#else /* STAGING_CSMT */ - surface_validate_location(surface, location); - - if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM)) - surface_evict_sysmem(surface); - - return WINED3D_OK; -#endif /* STAGING_CSMT */ -} - -static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; } -/* Context activation is done by the caller. */ -static void ffp_blit_free(struct wined3d_device *device) { } - -/* Context activation is done by the caller. */ -static HRESULT ffp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface, - const struct wined3d_color_key *color_key) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - gl_info->gl_ops.gl.p_glEnable(surface->container->target); - checkGLcall("glEnable(target)"); - - return WINED3D_OK; } /* Context activation is done by the caller. */ -static void ffp_blit_unset(const struct wined3d_gl_info *gl_info) +static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); - checkGLcall("glDisable(GL_TEXTURE_2D)"); - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_destroy(next, context); +} + +static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil) +{ + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_clear(next, device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); +} + +static void fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter) +{ + struct wined3d_resource *src_resource = &src_surface->container->resource; + struct wined3d_resource *dst_resource = &dst_surface->container->resource; + struct wined3d_device *device = dst_resource->device; + struct wined3d_blitter *next; + + if (!fbo_blitter_supported(&device->adapter->gl_info, op, + src_resource->usage, src_resource->pool, src_resource->format, src_location, + src_resource->usage, dst_resource->pool, dst_resource->format, dst_location)) { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + if ((next = blitter->next)) + next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, colour_key, filter); + return; } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + + if (op == WINED3D_BLIT_OP_COLOR_BLIT) { - gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); - checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + TRACE("Colour blit.\n"); + surface_blt_fbo(device, context, filter, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect); + return; } + + if (op == WINED3D_BLIT_OP_DEPTH_BLIT) + { + TRACE("Depth/stencil blit.\n"); + surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect); + return; + } + + ERR("This blitter does not implement blit op %#x.\n", op); +} + +static const struct wined3d_blitter_ops fbo_blitter_ops = +{ + fbo_blitter_destroy, + fbo_blitter_clear, + fbo_blitter_blit, +}; + +void wined3d_fbo_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) +{ + struct wined3d_blitter *blitter; + + if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer) + return; + + if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + return; + + TRACE("Created blitter %p.\n", blitter); + + blitter->ops = &fbo_blitter_ops; + blitter->next = *next; + *next = blitter; +} + +/* Context activation is done by the caller. */ +static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) +{ + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_destroy(next, context); } static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) + DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, DWORD src_location, + DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format, DWORD dst_location) { - if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM) + BOOL decompress; + + decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED); + if (!decompress && (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)) { TRACE("Source or destination is in system memory.\n"); return FALSE; @@ -4897,7 +2658,10 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, } case WINED3D_BLIT_OP_COLOR_BLIT: case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST: - if (TRACE_ON(d3d_surface) && TRACE_ON(d3d)) + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + return FALSE; + + if (TRACE_ON(d3d)) { TRACE("Checking support for fixup:\n"); dump_color_fixup_desc(src_format->color_fixup); @@ -4907,8 +2671,16 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, if (!is_identity_fixup(src_format->color_fixup) || !is_identity_fixup(dst_format->color_fixup)) { - TRACE("Fixups are not supported.\n"); - return FALSE; + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER + && dst_format->id == src_format->id && dst_location == WINED3D_LOCATION_DRAWABLE) + { + WARN("Claiming fixup support because of ORM_BACKBUFFER.\n"); + } + else + { + TRACE("Fixups are not supported.\n"); + return FALSE; + } } if (!(dst_usage & WINED3DUSAGE_RENDERTARGET)) @@ -4918,144 +2690,237 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, } return TRUE; - case WINED3D_BLIT_OP_COLOR_FILL: - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (dst_usage & WINED3DUSAGE_RENDERTARGET))) - return FALSE; - } - else if (!(dst_usage & WINED3DUSAGE_RENDERTARGET)) - { - TRACE("Color fill not supported\n"); - return FALSE; - } - - /* FIXME: We should reject color fills on formats with fixups, - * but this would break P8 color fills for example. */ - - return TRUE; - - case WINED3D_BLIT_OP_DEPTH_FILL: - return TRUE; - default: TRACE("Unsupported blit_op=%d\n", blit_op); return FALSE; } } -static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) +static BOOL ffp_blitter_use_cpu_clear(struct wined3d_rendertarget_view *view) { - const RECT draw_rect = {0, 0, view->width, view->height}; -#if defined(STAGING_CSMT) - struct wined3d_fb_state fb = {&view, NULL, 1}; -#else /* STAGING_CSMT */ - struct wined3d_fb_state fb = {&view, NULL}; -#endif /* STAGING_CSMT */ + struct wined3d_resource *resource; + struct wined3d_texture *texture; - device_clear_render_targets(device, 1, &fb, 1, rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); + resource = view->resource; + if (resource->type == WINED3D_RTYPE_BUFFER) + return FALSE; - return WINED3D_OK; + texture = texture_from_resource(resource); + if (!(texture->flags & WINED3D_TEXTURE_PIN_SYSMEM)) + return FALSE; + + return texture->sub_resources[view->sub_resource_idx].locations & resource->map_binding; } -static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, - struct wined3d_rendertarget_view *view, const RECT *rect, float depth) +static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil) { - const RECT draw_rect = {0, 0, view->width, view->height}; - struct wined3d_fb_state fb = {NULL, view}; + struct wined3d_rendertarget_view *view; + struct wined3d_resource *resource; + struct wined3d_blitter *next; + unsigned int i; - device_clear_render_targets(device, 0, &fb, 1, rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); + if (flags & WINED3DCLEAR_TARGET) + { + for (i = 0; i < rt_count; ++i) + { + if (!(view = fb->render_targets[i])) + continue; - return WINED3D_OK; + resource = view->resource; + if (resource->pool == WINED3D_POOL_SYSTEM_MEM) + goto next; + + if (!(flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + && ffp_blitter_use_cpu_clear(view)) + goto next; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (!((view->format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) + || (resource->usage & WINED3DUSAGE_RENDERTARGET))) + goto next; + } + else if (!(resource->usage & WINED3DUSAGE_RENDERTARGET)) + { + goto next; + } + + /* FIXME: We should reject colour fills on formats with fixups, + * but this would break P8 colour fills for example. */ + } + } + + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { + view = fb->depth_stencil; + if (view && (view->resource->pool == WINED3D_POOL_SYSTEM_MEM + || ffp_blitter_use_cpu_clear(view))) + goto next; + } + + device_clear_render_targets(device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); + return; + +next: + if ((next = blitter->next)) + next->ops->blitter_clear(next, device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); } -static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op, DWORD filter, - struct wined3d_surface *src_surface, const RECT *src_rect, - struct wined3d_surface *dst_surface, const RECT *dst_rect, - const struct wined3d_color_key *color_key) +static void ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) { - struct wined3d_context *context; + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_texture *dst_texture = dst_surface->container; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_resource *src_resource, *dst_resource; + struct wined3d_color_key old_blt_key; + struct wined3d_device *device; + struct wined3d_blitter *next; + DWORD old_color_key_flags; + RECT r; - /* Blit from offscreen surface to render target */ - struct wined3d_color_key old_blt_key = src_surface->container->async.src_blt_color_key; - DWORD old_color_key_flags = src_surface->container->async.color_key_flags; + src_resource = &src_texture->resource; + dst_resource = &dst_texture->resource; + device = dst_resource->device; + + if (!ffp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op, + src_resource->usage, src_resource->pool, src_resource->format, src_location, + dst_resource->usage, dst_resource->pool, dst_resource->format, dst_location)) + { + if ((next = blitter->next)) + next->ops->blitter_blit(next, op, context, src_surface, src_location, + src_rect, dst_surface, dst_location, dst_rect, color_key, filter); + return; + } TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); - wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, color_key); + old_blt_key = src_texture->async.src_blt_color_key; + old_color_key_flags = src_texture->async.color_key_flags; + wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, color_key); - context = context_acquire(device, dst_surface); + /* Make sure the surface is up-to-date. This should probably use + * surface_load_location() and worry about the destination surface too, + * unless we're overwriting it completely. */ + wined3d_texture_load(src_texture, context, FALSE); - if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) - glEnable(GL_ALPHA_TEST); + /* Activate the destination context, set it up for blitting. */ + context_apply_blit_state(context, device); - surface_blt_to_drawable(device, context, filter, - !!color_key, src_surface, src_rect, dst_surface, dst_rect); - - if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) - glDisable(GL_ALPHA_TEST); - - context_release(context); - - /* Restore the color key parameters */ - wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, - (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); - -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); -#else /* STAGING_CSMT */ - surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); - surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); -#endif /* STAGING_CSMT */ -} - -const struct blit_shader ffp_blit = { - ffp_blit_alloc, - ffp_blit_free, - ffp_blit_set, - ffp_blit_unset, - ffp_blit_supported, - ffp_blit_color_fill, - ffp_blit_depth_fill, - ffp_blit_blit_surface, -}; - -static HRESULT cpu_blit_alloc(struct wined3d_device *device) -{ - return WINED3D_OK; -} - -/* Context activation is done by the caller. */ -static void cpu_blit_free(struct wined3d_device *device) -{ -} - -/* Context activation is done by the caller. */ -static HRESULT cpu_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface, - const struct wined3d_color_key *color_key) -{ - return WINED3D_OK; -} - -/* Context activation is done by the caller. */ -static void cpu_blit_unset(const struct wined3d_gl_info *gl_info) -{ -} - -static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) -{ - if (blit_op == WINED3D_BLIT_OP_COLOR_FILL) + if (dst_location == WINED3D_LOCATION_DRAWABLE) { - return TRUE; + r = *dst_rect; + surface_translate_drawable_coords(dst_surface, context->win_handle, &r); + dst_rect = &r; } - return FALSE; + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + GLenum buffer; + + if (dst_location == WINED3D_LOCATION_DRAWABLE) + { + TRACE("Destination surface %p is onscreen.\n", dst_surface); + buffer = wined3d_texture_get_gl_buffer(dst_texture); + } + else + { + TRACE("Destination surface %p is offscreen.\n", dst_surface); + buffer = GL_COLOR_ATTACHMENT0; + } + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location); + context_set_draw_buffer(context, buffer); + context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER); + context_invalidate_state(context, STATE_FRAMEBUFFER); + } + + gl_info->gl_ops.gl.p_glEnable(src_texture->target); + checkGLcall("glEnable(target)"); + + if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key) + { + gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); + checkGLcall("glEnable(GL_ALPHA_TEST)"); + } + + if (color_key) + { + /* For P8 surfaces, the alpha component contains the palette index. + * Which means that the colorkey is one of the palette entries. In + * other cases pixels that should be masked away have alpha set to 0. */ + if (src_texture->resource.format->id == WINED3DFMT_P8_UINT) + gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, + (float)src_texture->async.src_blt_color_key.color_space_low_value / 255.0f); + else + gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f); + checkGLcall("glAlphaFunc"); + } + + draw_textured_quad(src_surface, context, src_rect, dst_rect, filter); + + if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key) + { + gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); + checkGLcall("glDisable(GL_ALPHA_TEST)"); + } + + /* Leave the OpenGL state valid for blitting. */ + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + + if (wined3d_settings.strict_draw_ordering + || (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + /* Restore the color key parameters */ + wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, + (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); +} + +static const struct wined3d_blitter_ops ffp_blitter_ops = +{ + ffp_blitter_destroy, + ffp_blitter_clear, + ffp_blitter_blit, +}; + +void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info) +{ + struct wined3d_blitter *blitter; + + if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + return; + + TRACE("Created blitter %p.\n", blitter); + + blitter->ops = &ffp_blitter_ops; + blitter->next = *next; + *next = blitter; +} + +/* Context activation is done by the caller. */ +static void cpu_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) +{ + struct wined3d_blitter *next; + + if ((next = blitter->next)) + next->ops->blitter_destroy(next, context); } static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data, @@ -5161,558 +3026,405 @@ static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data, return E_NOTIMPL; } -static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) +static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx, + enum wined3d_texture_filter_type filter) { -#if defined(STAGING_CSMT) - int bpp, srcheight, srcwidth, dstheight, dstwidth, width; + unsigned int bpp, src_height, src_width, dst_height, dst_width, row_byte_count; + struct wined3d_device *device = dst_texture->resource.device; const struct wined3d_format *src_format, *dst_format; + struct wined3d_texture *converted_texture = NULL; + struct wined3d_bo_address src_data, dst_data; unsigned int src_fmt_flags, dst_fmt_flags; - struct wined3d_texture *src_texture = NULL; - void *src_data = NULL, *dst_data = NULL; - UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - const BYTE *sbase = NULL; + struct wined3d_map_desc dst_map, src_map; + struct wined3d_context *context = NULL; + unsigned int x, sx, xinc, y, sy, yinc; + unsigned int texture_level; HRESULT hr = WINED3D_OK; + BOOL same_sub_resource; + DWORD map_binding; + const BYTE *sbase; const BYTE *sbuf; BYTE *dbuf; - int x, y; - struct wined3d_device *device = dst_surface->resource.device; - struct wined3d_context *context = NULL; - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); + TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, " + "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n", + dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, + src_sub_resource_idx, debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter)); if (device->d3d_initialized) - context = context_acquire(device, NULL); + context = context_acquire(device, NULL, 0); - if (!wined3d_resource_prepare_map_memory(&dst_surface->resource, context)) + if (src_texture == dst_texture && src_sub_resource_idx == dst_sub_resource_idx) { - hr = E_OUTOFMEMORY; - goto error; - } - wined3d_resource_load_location(&dst_surface->resource, context, dst_surface->resource.map_binding); + same_sub_resource = TRUE; - if (src_surface == dst_surface) - { - dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); - wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); - src_data = dst_data; - src_row_pitch = dst_row_pitch; -#else /* STAGING_CSMT */ - const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; - int bpp, srcheight, srcwidth, dstheight, dstwidth, width; - const struct wined3d_format *src_format, *dst_format; - unsigned int src_fmt_flags, dst_fmt_flags; - struct wined3d_texture *src_texture = NULL; - struct wined3d_map_desc dst_map, src_map; - const BYTE *sbase = NULL; - HRESULT hr = WINED3D_OK; - const BYTE *sbuf; - BYTE *dbuf; - int x, y; + map_binding = dst_texture->resource.map_binding; + texture_level = dst_sub_resource_idx % dst_texture->level_count; + if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, map_binding)) + ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); + wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); + wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + dst_map.data = context_map_bo_address(context, &dst_data, + dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); - - if (src_surface == dst_surface) - { - wined3d_surface_map(dst_surface, &dst_map, NULL, 0); src_map = dst_map; -#endif /* STAGING_CSMT */ - src_format = dst_surface->resource.format; + src_format = dst_texture->resource.format; dst_format = src_format; - dst_fmt_flags = dst_surface->container->resource.format_flags; + dst_fmt_flags = dst_texture->resource.format_flags; src_fmt_flags = dst_fmt_flags; } else { - dst_format = dst_surface->resource.format; - dst_fmt_flags = dst_surface->container->resource.format_flags; - if (src_surface) + same_sub_resource = FALSE; + dst_format = dst_texture->resource.format; + dst_fmt_flags = dst_texture->resource.format_flags; + if (dst_texture->resource.format->id != src_texture->resource.format->id) { -#if defined(STAGING_CSMT) - if (!wined3d_resource_prepare_map_memory(&src_surface->resource, context)) + if (!(converted_texture = surface_convert_format(src_texture, src_sub_resource_idx, dst_format))) { - hr = E_OUTOFMEMORY; - goto error; + FIXME("Cannot convert %s to %s.\n", debug_d3dformat(src_texture->resource.format->id), + debug_d3dformat(dst_texture->resource.format->id)); + if (context) + context_release(context); + return WINED3DERR_NOTAVAILABLE; } - -#endif /* STAGING_CSMT */ - if (dst_surface->resource.format->id != src_surface->resource.format->id) - { - if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) - { - /* The conv function writes a FIXME */ - WARN("Cannot convert source surface format to dest format.\n"); - goto release; - } - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); - } -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, context, src_surface->resource.map_binding); - wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); - src_data = wined3d_resource_get_map_ptr(&src_surface->resource, context, 0); -#else /* STAGING_CSMT */ - wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); -#endif /* STAGING_CSMT */ - src_format = src_surface->resource.format; - src_fmt_flags = src_surface->container->resource.format_flags; - } - else - { - src_format = dst_format; - src_fmt_flags = dst_fmt_flags; + src_texture = converted_texture; + src_sub_resource_idx = 0; } + src_format = src_texture->resource.format; + src_fmt_flags = src_texture->resource.format_flags; -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); - dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); -#else /* STAGING_CSMT */ - wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0); -#endif /* STAGING_CSMT */ + map_binding = src_texture->resource.map_binding; + texture_level = src_sub_resource_idx % src_texture->level_count; + if (!wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, map_binding)) + ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_get_pitch(src_texture, texture_level, &src_map.row_pitch, &src_map.slice_pitch); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &src_data, map_binding); + src_map.data = context_map_bo_address(context, &src_data, + src_texture->sub_resources[src_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); + + map_binding = dst_texture->resource.map_binding; + texture_level = dst_sub_resource_idx % dst_texture->level_count; + if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, map_binding)) + ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); + wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); + wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + dst_map.data = context_map_bo_address(context, &dst_data, + dst_texture->sub_resources[dst_sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); } - bpp = dst_surface->resource.format->byte_count; - srcheight = src_rect->bottom - src_rect->top; - srcwidth = src_rect->right - src_rect->left; - dstheight = dst_rect->bottom - dst_rect->top; - dstwidth = dst_rect->right - dst_rect->left; - width = (dst_rect->right - dst_rect->left) * bpp; + bpp = dst_format->byte_count; + src_height = src_box->bottom - src_box->top; + src_width = src_box->right - src_box->left; + dst_height = dst_box->bottom - dst_box->top; + dst_width = dst_box->right - dst_box->left; + row_byte_count = dst_width * bpp; - if (src_surface) -#if defined(STAGING_CSMT) - sbase = (BYTE *)src_data - + ((src_rect->top / src_format->block_height) * src_row_pitch) - + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); - dbuf = (BYTE *)dst_data - + ((dst_rect->top / dst_format->block_height) * dst_row_pitch) - + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); -#else /* STAGING_CSMT */ - sbase = (BYTE *)src_map.data - + ((src_rect->top / src_format->block_height) * src_map.row_pitch) - + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); - if (src_surface != dst_surface) - dbuf = dst_map.data; - else - dbuf = (BYTE *)dst_map.data - + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch) - + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); -#endif /* STAGING_CSMT */ + sbase = (BYTE *)src_map.data + + ((src_box->top / src_format->block_height) * src_map.row_pitch) + + ((src_box->left / src_format->block_width) * src_format->block_byte_count); + dbuf = (BYTE *)dst_map.data + + ((dst_box->top / dst_format->block_height) * dst_map.row_pitch) + + ((dst_box->left / dst_format->block_width) * dst_format->block_byte_count); if (src_fmt_flags & dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) { TRACE("%s -> %s copy.\n", debug_d3dformat(src_format->id), debug_d3dformat(dst_format->id)); - if (src_surface == dst_surface) + if (same_sub_resource) { FIXME("Only plain blits supported on compressed surfaces.\n"); hr = E_NOTIMPL; goto release; } - if (srcheight != dstheight || srcwidth != dstwidth) + if (src_height != dst_height || src_width != dst_width) { WARN("Stretching not supported on compressed surfaces.\n"); hr = WINED3DERR_INVALIDCALL; goto release; } - if (!surface_check_block_align_rect(src_surface, src_rect)) - { - WARN("Source rectangle not block-aligned.\n"); - hr = WINED3DERR_INVALIDCALL; - goto release; - } - - if (!surface_check_block_align_rect(dst_surface, dst_rect)) - { - WARN("Destination rectangle not block-aligned.\n"); - hr = WINED3DERR_INVALIDCALL; - goto release; - } - hr = surface_cpu_blt_compressed(sbase, dbuf, -#if defined(STAGING_CSMT) - src_row_pitch, dst_row_pitch, dstwidth, dstheight, -#else /* STAGING_CSMT */ - src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight, -#endif /* STAGING_CSMT */ + src_map.row_pitch, dst_map.row_pitch, dst_width, dst_height, src_format, flags, fx); goto release; } - /* First, all the 'source-less' blits */ - if (flags & WINED3D_BLT_COLOR_FILL) + if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT + && (src_width != dst_width || src_height != dst_height)) { -#if defined(STAGING_CSMT) - hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_row_pitch, fx->fill_color); -#else /* STAGING_CSMT */ - hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->fill_color); -#endif /* STAGING_CSMT */ - flags &= ~WINED3D_BLT_COLOR_FILL; + /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */ + static int once; + if (!once++) FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter)); } - if (flags & WINED3D_BLT_DEPTH_FILL) - FIXME("WINED3D_BLT_DEPTH_FILL needs to be implemented!\n"); + xinc = (src_width << 16) / dst_width; + yinc = (src_height << 16) / dst_height; - /* Now the 'with source' blits. */ - if (src_surface) + if (!flags) { - int sx, xinc, sy, yinc; - - if (!dstwidth || !dstheight) /* Hmm... stupid program? */ - goto release; - - if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT - && (srcwidth != dstwidth || srcheight != dstheight)) + /* No effects, we can cheat here. */ + if (dst_width == src_width) { - /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */ - static int once; - if (!once++) FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter)); - } - - xinc = (srcwidth << 16) / dstwidth; - yinc = (srcheight << 16) / dstheight; - - if (!flags) - { - /* No effects, we can cheat here. */ - if (dstwidth == srcwidth) + if (dst_height == src_height) { - if (dstheight == srcheight) - { - /* No stretching in either direction. This needs to be as - * fast as possible. */ - sbuf = sbase; + /* No stretching in either direction. This needs to be as fast + * as possible. */ + sbuf = sbase; - /* Check for overlapping surfaces. */ - if (src_surface != dst_surface || dst_rect->top < src_rect->top - || dst_rect->right <= src_rect->left || src_rect->right <= dst_rect->left) + /* Check for overlapping surfaces. */ + if (!same_sub_resource || dst_box->top < src_box->top + || dst_box->right <= src_box->left || src_box->right <= dst_box->left) + { + /* No overlap, or dst above src, so copy from top downwards. */ + for (y = 0; y < dst_height; ++y) { - /* No overlap, or dst above src, so copy from top downwards. */ - for (y = 0; y < dstheight; ++y) - { - memcpy(dbuf, sbuf, width); -#if defined(STAGING_CSMT) - sbuf += src_row_pitch; - dbuf += dst_row_pitch; - } + memcpy(dbuf, sbuf, row_byte_count); + sbuf += src_map.row_pitch; + dbuf += dst_map.row_pitch; } - else if (dst_rect->top > src_rect->top) + } + else if (dst_box->top > src_box->top) + { + /* Copy from bottom upwards. */ + sbuf += src_map.row_pitch * dst_height; + dbuf += dst_map.row_pitch * dst_height; + for (y = 0; y < dst_height; ++y) { - /* Copy from bottom upwards. */ - sbuf += src_row_pitch * dstheight; - dbuf += dst_row_pitch * dstheight; - for (y = 0; y < dstheight; ++y) - { - sbuf -= src_row_pitch; - dbuf -= dst_row_pitch; -#else /* STAGING_CSMT */ - sbuf += src_map.row_pitch; - dbuf += dst_map.row_pitch; - } - } - else if (dst_rect->top > src_rect->top) - { - /* Copy from bottom upwards. */ - sbuf += src_map.row_pitch * dstheight; - dbuf += dst_map.row_pitch * dstheight; - for (y = 0; y < dstheight; ++y) - { - sbuf -= src_map.row_pitch; - dbuf -= dst_map.row_pitch; -#endif /* STAGING_CSMT */ - memcpy(dbuf, sbuf, width); - } - } - else - { - /* Src and dst overlapping on the same line, use memmove. */ - for (y = 0; y < dstheight; ++y) - { - memmove(dbuf, sbuf, width); -#if defined(STAGING_CSMT) - sbuf += src_row_pitch; - dbuf += dst_row_pitch; -#else /* STAGING_CSMT */ - sbuf += src_map.row_pitch; - dbuf += dst_map.row_pitch; -#endif /* STAGING_CSMT */ - } + sbuf -= src_map.row_pitch; + dbuf -= dst_map.row_pitch; + memcpy(dbuf, sbuf, row_byte_count); } } else { - /* Stretching in y direction only. */ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) + /* Src and dst overlapping on the same line, use memmove. */ + for (y = 0; y < dst_height; ++y) { -#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; - memcpy(dbuf, sbuf, width); - dbuf += dst_row_pitch; -#else /* STAGING_CSMT */ - sbuf = sbase + (sy >> 16) * src_map.row_pitch; - memcpy(dbuf, sbuf, width); + memmove(dbuf, sbuf, row_byte_count); + sbuf += src_map.row_pitch; dbuf += dst_map.row_pitch; -#endif /* STAGING_CSMT */ } } } else { - /* Stretching in X direction. */ - int last_sy = -1; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) + /* Stretching in y direction only. */ + for (y = sy = 0; y < dst_height; ++y, sy += yinc) { -#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; - - if ((sy >> 16) == (last_sy >> 16)) - { - /* This source row is the same as last source row - - * Copy the already stretched row. */ - memcpy(dbuf, dbuf - dst_row_pitch, width); -#else /* STAGING_CSMT */ sbuf = sbase + (sy >> 16) * src_map.row_pitch; + memcpy(dbuf, sbuf, row_byte_count); + dbuf += dst_map.row_pitch; + } + } + } + else + { + /* Stretching in X direction. */ + unsigned int last_sy = ~0u; + for (y = sy = 0; y < dst_height; ++y, sy += yinc) + { + sbuf = sbase + (sy >> 16) * src_map.row_pitch; - if ((sy >> 16) == (last_sy >> 16)) - { - /* This source row is the same as last source row - - * Copy the already stretched row. */ - memcpy(dbuf, dbuf - dst_map.row_pitch, width); -#endif /* STAGING_CSMT */ - } - else - { + if ((sy >> 16) == (last_sy >> 16)) + { + /* This source row is the same as last source row - + * Copy the already stretched row. */ + memcpy(dbuf, dbuf - dst_map.row_pitch, row_byte_count); + } + else + { #define STRETCH_ROW(type) \ do { \ const type *s = (const type *)sbuf; \ type *d = (type *)dbuf; \ - for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ + for (x = sx = 0; x < dst_width; ++x, sx += xinc) \ d[x] = s[sx >> 16]; \ } while(0) - switch(bpp) + switch(bpp) + { + case 1: + STRETCH_ROW(BYTE); + break; + case 2: + STRETCH_ROW(WORD); + break; + case 4: + STRETCH_ROW(DWORD); + break; + case 3: { - case 1: - STRETCH_ROW(BYTE); - break; - case 2: - STRETCH_ROW(WORD); - break; - case 4: - STRETCH_ROW(DWORD); - break; - case 3: + const BYTE *s; + BYTE *d = dbuf; + for (x = sx = 0; x < dst_width; x++, sx+= xinc) { - const BYTE *s; - BYTE *d = dbuf; - for (x = sx = 0; x < dstwidth; x++, sx+= xinc) - { - DWORD pixel; + DWORD pixel; - s = sbuf + 3 * (sx >> 16); - pixel = s[0] | (s[1] << 8) | (s[2] << 16); - d[0] = (pixel ) & 0xff; - d[1] = (pixel >> 8) & 0xff; - d[2] = (pixel >> 16) & 0xff; - d += 3; - } - break; + s = sbuf + 3 * (sx >> 16); + pixel = s[0] | (s[1] << 8) | (s[2] << 16); + d[0] = (pixel ) & 0xff; + d[1] = (pixel >> 8) & 0xff; + d[2] = (pixel >> 16) & 0xff; + d += 3; } - default: - FIXME("Stretched blit not implemented for bpp %u!\n", bpp * 8); - hr = WINED3DERR_NOTAVAILABLE; - goto error; + break; } -#undef STRETCH_ROW + default: + FIXME("Stretched blit not implemented for bpp %u.\n", bpp * 8); + hr = WINED3DERR_NOTAVAILABLE; + goto error; } -#if defined(STAGING_CSMT) - dbuf += dst_row_pitch; - last_sy = sy; +#undef STRETCH_ROW } + dbuf += dst_map.row_pitch; + last_sy = sy; } } - else + } + else + { + LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; + DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; + DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; + if (flags & (WINED3D_BLT_SRC_CKEY | WINED3D_BLT_DST_CKEY + | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_DST_CKEY_OVERRIDE)) { - LONG dstyinc = dst_row_pitch, dstxinc = bpp; -#else /* STAGING_CSMT */ - dbuf += dst_map.row_pitch; - last_sy = sy; - } + /* The color keying flags are checked for correctness in ddraw. */ + if (flags & WINED3D_BLT_SRC_CKEY) + { + keylow = src_texture->async.src_blt_color_key.color_space_low_value; + keyhigh = src_texture->async.src_blt_color_key.color_space_high_value; } + else if (flags & WINED3D_BLT_SRC_CKEY_OVERRIDE) + { + keylow = fx->src_color_key.color_space_low_value; + keyhigh = fx->src_color_key.color_space_high_value; + } + + if (flags & WINED3D_BLT_DST_CKEY) + { + /* Destination color keys are taken from the source surface! */ + destkeylow = src_texture->async.dst_blt_color_key.color_space_low_value; + destkeyhigh = src_texture->async.dst_blt_color_key.color_space_high_value; + } + else if (flags & WINED3D_BLT_DST_CKEY_OVERRIDE) + { + destkeylow = fx->dst_color_key.color_space_low_value; + destkeyhigh = fx->dst_color_key.color_space_high_value; + } + + if (bpp == 1) + { + keymask = 0xff; + } + else + { + DWORD masks[3]; + get_color_masks(src_format, masks); + keymask = masks[0] | masks[1] | masks[2]; + } + flags &= ~(WINED3D_BLT_SRC_CKEY | WINED3D_BLT_DST_CKEY + | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_DST_CKEY_OVERRIDE); } - else + + if (flags & WINED3D_BLT_FX) { - LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; -#endif /* STAGING_CSMT */ - DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; - DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; - if (flags & (WINED3D_BLT_SRC_CKEY | WINED3D_BLT_DST_CKEY - | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_DST_CKEY_OVERRIDE)) + BYTE *dTopLeft, *dTopRight, *dBottomLeft, *dBottomRight, *tmp; + LONG tmpxy; + dTopLeft = dbuf; + dTopRight = dbuf + ((dst_width - 1) * bpp); + dBottomLeft = dTopLeft + ((dst_height - 1) * dst_map.row_pitch); + dBottomRight = dBottomLeft + ((dst_width - 1) * bpp); + + if (fx->fx & WINEDDBLTFX_ARITHSTRETCHY) { - /* The color keying flags are checked for correctness in ddraw */ - if (flags & WINED3D_BLT_SRC_CKEY) - { - keylow = src_surface->container->async.src_blt_color_key.color_space_low_value; - keyhigh = src_surface->container->async.src_blt_color_key.color_space_high_value; - } - else if (flags & WINED3D_BLT_SRC_CKEY_OVERRIDE) - { - keylow = fx->src_color_key.color_space_low_value; - keyhigh = fx->src_color_key.color_space_high_value; - } - - if (flags & WINED3D_BLT_DST_CKEY) - { - /* Destination color keys are taken from the source surface! */ - destkeylow = src_surface->container->async.dst_blt_color_key.color_space_low_value; - destkeyhigh = src_surface->container->async.dst_blt_color_key.color_space_high_value; - } - else if (flags & WINED3D_BLT_DST_CKEY_OVERRIDE) - { - destkeylow = fx->dst_color_key.color_space_low_value; - destkeyhigh = fx->dst_color_key.color_space_high_value; - } - - if (bpp == 1) - { - keymask = 0xff; - } - else - { - DWORD masks[3]; - get_color_masks(src_format, masks); - keymask = masks[0] - | masks[1] - | masks[2]; - } - flags &= ~(WINED3D_BLT_SRC_CKEY | WINED3D_BLT_DST_CKEY - | WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_DST_CKEY_OVERRIDE); + /* I don't think we need to do anything about this flag. */ + WARN("Nothing done for WINEDDBLTFX_ARITHSTRETCHY.\n"); } - - if (flags & WINED3D_BLT_FX) + if (fx->fx & WINEDDBLTFX_MIRRORLEFTRIGHT) { - BYTE *dTopLeft, *dTopRight, *dBottomLeft, *dBottomRight, *tmp; - LONG tmpxy; - dTopLeft = dbuf; - dTopRight = dbuf + ((dstwidth - 1) * bpp); -#if defined(STAGING_CSMT) - dBottomLeft = dTopLeft + ((dstheight - 1) * dst_row_pitch); -#else /* STAGING_CSMT */ - dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch); -#endif /* STAGING_CSMT */ - dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp); - - if (fx->fx & WINEDDBLTFX_ARITHSTRETCHY) - { - /* I don't think we need to do anything about this flag */ - WARN("Nothing done for WINEDDBLTFX_ARITHSTRETCHY.\n"); - } - if (fx->fx & WINEDDBLTFX_MIRRORLEFTRIGHT) - { - tmp = dTopRight; - dTopRight = dTopLeft; - dTopLeft = tmp; - tmp = dBottomRight; - dBottomRight = dBottomLeft; - dBottomLeft = tmp; - dstxinc = dstxinc * -1; - } - if (fx->fx & WINEDDBLTFX_MIRRORUPDOWN) - { - tmp = dTopLeft; - dTopLeft = dBottomLeft; - dBottomLeft = tmp; - tmp = dTopRight; - dTopRight = dBottomRight; - dBottomRight = tmp; - dstyinc = dstyinc * -1; - } - if (fx->fx & WINEDDBLTFX_NOTEARING) - { - /* I don't think we need to do anything about this flag */ - WARN("Nothing done for WINEDDBLTFX_NOTEARING.\n"); - } - if (fx->fx & WINEDDBLTFX_ROTATE180) - { - tmp = dBottomRight; - dBottomRight = dTopLeft; - dTopLeft = tmp; - tmp = dBottomLeft; - dBottomLeft = dTopRight; - dTopRight = tmp; - dstxinc = dstxinc * -1; - dstyinc = dstyinc * -1; - } - if (fx->fx & WINEDDBLTFX_ROTATE270) - { - tmp = dTopLeft; - dTopLeft = dBottomLeft; - dBottomLeft = dBottomRight; - dBottomRight = dTopRight; - dTopRight = tmp; - tmpxy = dstxinc; - dstxinc = dstyinc; - dstyinc = tmpxy; - dstxinc = dstxinc * -1; - } - if (fx->fx & WINEDDBLTFX_ROTATE90) - { - tmp = dTopLeft; - dTopLeft = dTopRight; - dTopRight = dBottomRight; - dBottomRight = dBottomLeft; - dBottomLeft = tmp; - tmpxy = dstxinc; - dstxinc = dstyinc; - dstyinc = tmpxy; - dstyinc = dstyinc * -1; - } - if (fx->fx & WINEDDBLTFX_ZBUFFERBASEDEST) - { - /* I don't think we need to do anything about this flag */ - WARN("Nothing done for WINEDDBLTFX_ZBUFFERBASEDEST.\n"); - } - dbuf = dTopLeft; - flags &= ~(WINED3D_BLT_FX); + tmp = dTopRight; + dTopRight = dTopLeft; + dTopLeft = tmp; + tmp = dBottomRight; + dBottomRight = dBottomLeft; + dBottomLeft = tmp; + dstxinc = dstxinc * -1; } + if (fx->fx & WINEDDBLTFX_MIRRORUPDOWN) + { + tmp = dTopLeft; + dTopLeft = dBottomLeft; + dBottomLeft = tmp; + tmp = dTopRight; + dTopRight = dBottomRight; + dBottomRight = tmp; + dstyinc = dstyinc * -1; + } + if (fx->fx & WINEDDBLTFX_NOTEARING) + { + /* I don't think we need to do anything about this flag. */ + WARN("Nothing done for WINEDDBLTFX_NOTEARING.\n"); + } + if (fx->fx & WINEDDBLTFX_ROTATE180) + { + tmp = dBottomRight; + dBottomRight = dTopLeft; + dTopLeft = tmp; + tmp = dBottomLeft; + dBottomLeft = dTopRight; + dTopRight = tmp; + dstxinc = dstxinc * -1; + dstyinc = dstyinc * -1; + } + if (fx->fx & WINEDDBLTFX_ROTATE270) + { + tmp = dTopLeft; + dTopLeft = dBottomLeft; + dBottomLeft = dBottomRight; + dBottomRight = dTopRight; + dTopRight = tmp; + tmpxy = dstxinc; + dstxinc = dstyinc; + dstyinc = tmpxy; + dstxinc = dstxinc * -1; + } + if (fx->fx & WINEDDBLTFX_ROTATE90) + { + tmp = dTopLeft; + dTopLeft = dTopRight; + dTopRight = dBottomRight; + dBottomRight = dBottomLeft; + dBottomLeft = tmp; + tmpxy = dstxinc; + dstxinc = dstyinc; + dstyinc = tmpxy; + dstyinc = dstyinc * -1; + } + if (fx->fx & WINEDDBLTFX_ZBUFFERBASEDEST) + { + /* I don't think we need to do anything about this flag. */ + WARN("Nothing done for WINEDDBLTFX_ZBUFFERBASEDEST.\n"); + } + dbuf = dTopLeft; + flags &= ~(WINED3D_BLT_FX); + } -#if defined(STAGING_CSMT) #define COPY_COLORKEY_FX(type) \ do { \ const type *s; \ type *d = (type *)dbuf, *dx, tmp; \ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ - { \ - s = (const type *)(sbase + (sy >> 16) * src_row_pitch); \ - dx = d; \ - for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ - { \ - tmp = s[sx >> 16]; \ - if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \ - && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \ - { \ - dx[0] = tmp; \ - } \ - dx = (type *)(((BYTE *)dx) + dstxinc); \ - } \ - d = (type *)(((BYTE *)d) + dstyinc); \ - } \ -} while(0) -#else /* STAGING_CSMT */ -#define COPY_COLORKEY_FX(type) \ -do { \ - const type *s; \ - type *d = (type *)dbuf, *dx, tmp; \ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ + for (y = sy = 0; y < dst_height; ++y, sy += yinc) \ { \ s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \ dx = d; \ - for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ + for (x = sx = 0; x < dst_width; ++x, sx += xinc) \ { \ tmp = s[sx >> 16]; \ if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \ @@ -5725,175 +3437,312 @@ do { \ d = (type *)(((BYTE *)d) + dstyinc); \ } \ } while(0) -#endif /* STAGING_CSMT */ - switch (bpp) + switch (bpp) + { + case 1: + COPY_COLORKEY_FX(BYTE); + break; + case 2: + COPY_COLORKEY_FX(WORD); + break; + case 4: + COPY_COLORKEY_FX(DWORD); + break; + case 3: { - case 1: - COPY_COLORKEY_FX(BYTE); - break; - case 2: - COPY_COLORKEY_FX(WORD); - break; - case 4: - COPY_COLORKEY_FX(DWORD); - break; - case 3: + const BYTE *s; + BYTE *d = dbuf, *dx; + for (y = sy = 0; y < dst_height; ++y, sy += yinc) { - const BYTE *s; - BYTE *d = dbuf, *dx; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) + sbuf = sbase + (sy >> 16) * src_map.row_pitch; + dx = d; + for (x = sx = 0; x < dst_width; ++x, sx+= xinc) { -#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; -#else /* STAGING_CSMT */ - sbuf = sbase + (sy >> 16) * src_map.row_pitch; -#endif /* STAGING_CSMT */ - dx = d; - for (x = sx = 0; x < dstwidth; ++x, sx+= xinc) + DWORD pixel, dpixel = 0; + s = sbuf + 3 * (sx>>16); + pixel = s[0] | (s[1] << 8) | (s[2] << 16); + dpixel = dx[0] | (dx[1] << 8 ) | (dx[2] << 16); + if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) + && ((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh)) { - DWORD pixel, dpixel = 0; - s = sbuf + 3 * (sx>>16); - pixel = s[0] | (s[1] << 8) | (s[2] << 16); - dpixel = dx[0] | (dx[1] << 8 ) | (dx[2] << 16); - if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) - && ((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh)) - { - dx[0] = (pixel ) & 0xff; - dx[1] = (pixel >> 8) & 0xff; - dx[2] = (pixel >> 16) & 0xff; - } - dx += dstxinc; + dx[0] = (pixel ) & 0xff; + dx[1] = (pixel >> 8) & 0xff; + dx[2] = (pixel >> 16) & 0xff; } - d += dstyinc; + dx += dstxinc; } - break; + d += dstyinc; } - default: - FIXME("%s color-keyed blit not implemented for bpp %u!\n", - (flags & WINED3D_BLT_SRC_CKEY) ? "Source" : "Destination", bpp * 8); - hr = WINED3DERR_NOTAVAILABLE; - goto error; -#undef COPY_COLORKEY_FX + break; } + default: + FIXME("%s color-keyed blit not implemented for bpp %u.\n", + (flags & WINED3D_BLT_SRC_CKEY) ? "Source" : "Destination", bpp * 8); + hr = WINED3DERR_NOTAVAILABLE; + goto error; +#undef COPY_COLORKEY_FX } } -#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->resource.map_binding); - if (dst_surface->container) - wined3d_texture_set_dirty(dst_surface->container); - -#endif /* STAGING_CSMT */ error: - if (flags && FIXME_ON(d3d_surface)) - { - FIXME("\tUnsupported flags: %#x.\n", flags); - } + if (flags) + FIXME(" Unsupported flags %#x.\n", flags); release: -#if defined(STAGING_CSMT) - if (dst_data) - { - wined3d_resource_release_map_ptr(&dst_surface->resource, context); - - if (dst_surface->container->swapchain - && dst_surface->container == dst_surface->container->swapchain->front_buffer) - { - dst_surface->lockedRect = *dst_rect; - dst_surface->surface_ops->surface_frontbuffer_updated(dst_surface); - } - } - if (src_surface && src_surface != dst_surface && src_data) - wined3d_resource_release_map_ptr(&src_surface->resource, context); - /* Release the converted surface, if any. */ - if (src_texture) - wined3d_texture_decref(src_texture); + context_unmap_bo_address(context, &dst_data, GL_PIXEL_UNPACK_BUFFER); + if (!same_sub_resource) + context_unmap_bo_address(context, &src_data, GL_PIXEL_UNPACK_BUFFER); + if (converted_texture) + wined3d_texture_decref(converted_texture); if (context) context_release(context); -#else /* STAGING_CSMT */ - wined3d_surface_unmap(dst_surface); - if (src_surface && src_surface != dst_surface) - wined3d_surface_unmap(src_surface); - /* Release the converted surface, if any. */ - if (src_texture) - wined3d_texture_decref(src_texture); -#endif /* STAGING_CSMT */ return hr; } -static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) +static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, + const struct wined3d_box *box, const struct wined3d_color *colour) { - struct wined3d_surface *surface = wined3d_rendertarget_view_get_surface(view); - static const RECT src_rect; + struct wined3d_device *device = view->resource->device; + struct wined3d_context *context = NULL; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + unsigned int x, y, w, h, bpp; + struct wined3d_map_desc map; + DWORD map_binding; + BYTE *row; + DWORD c; + + TRACE("view %p, box %s, colour %s.\n", view, debug_box(box), debug_color(colour)); + + if (view->format_flags & WINED3DFMT_FLAG_BLOCKS) + { + FIXME("Not implemented for format %s.\n", debug_d3dformat(view->format->id)); + return; + } + + if (view->format->id != view->resource->format->id) + FIXME("View format %s doesn't match resource format %s.\n", + debug_d3dformat(view->format->id), debug_d3dformat(view->resource->format->id)); + + if (view->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for buffers.\n"); + return; + } + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + c = wined3d_format_convert_from_float(view->format, colour); + bpp = view->format->byte_count; + w = box->right - box->left; + h = box->bottom - box->top; + + texture = texture_from_resource(view->resource); + map_binding = texture->resource.map_binding; + if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding)) + ERR("Failed to load the sub-resource into %s.\n", wined3d_debug_location(map_binding)); + wined3d_texture_invalidate_location(texture, view->sub_resource_idx, ~map_binding); + wined3d_texture_get_pitch(texture, view->sub_resource_idx % texture->level_count, + &map.row_pitch, &map.slice_pitch); + wined3d_texture_get_memory(texture, view->sub_resource_idx, &data, map_binding); + map.data = context_map_bo_address(context, &data, + texture->sub_resources[view->sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); + map.data = (BYTE *)map.data + + (box->front * map.slice_pitch) + + ((box->top / view->format->block_height) * map.row_pitch) + + ((box->left / view->format->block_width) * view->format->block_byte_count); + + switch (bpp) + { + case 1: + for (x = 0; x < w; ++x) + { + ((BYTE *)map.data)[x] = c; + } + break; + + case 2: + for (x = 0; x < w; ++x) + { + ((WORD *)map.data)[x] = c; + } + break; + + case 3: + { + row = map.data; + for (x = 0; x < w; ++x, row += 3) + { + row[0] = (c ) & 0xff; + row[1] = (c >> 8) & 0xff; + row[2] = (c >> 16) & 0xff; + } + break; + } + case 4: + for (x = 0; x < w; ++x) + { + ((DWORD *)map.data)[x] = c; + } + break; + + default: + FIXME("Not implemented for bpp %u.\n", bpp); + wined3d_resource_unmap(view->resource, view->sub_resource_idx); + return; + } + + row = map.data; + for (y = 1; y < h; ++y) + { + row += map.row_pitch; + memcpy(row, map.data, w * bpp); + } + + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + if (context) + context_release(context); +} + +static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil) +{ + struct wined3d_color c = {depth, 0.0f, 0.0f, 0.0f}; + struct wined3d_rendertarget_view *view; + struct wined3d_box box; + unsigned int i, j; + + if (!rect_count) + { + rect_count = 1; + clear_rects = draw_rect; + } + + for (i = 0; i < rect_count; ++i) + { + box.left = max(clear_rects[i].left, draw_rect->left); + box.top = max(clear_rects[i].top, draw_rect->top); + box.right = min(clear_rects[i].right, draw_rect->right); + box.bottom = min(clear_rects[i].bottom, draw_rect->bottom); + box.front = 0; + box.back = 1; + + if (box.left >= box.right || box.top >= box.bottom) + continue; + + if (flags & WINED3DCLEAR_TARGET) + { + for (j = 0; j < rt_count; ++j) + { + if ((view = fb->render_targets[j])) + surface_cpu_blt_colour_fill(view, &box, colour); + } + } + + if ((flags & WINED3DCLEAR_ZBUFFER) && (view = fb->depth_stencil)) + surface_cpu_blt_colour_fill(view, &box, &c); + } + + if (flags & ~(WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER)) + FIXME("flags %#x not implemented.\n", flags); +} + +static void cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, + struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location, + const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter) +{ + struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; + struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; struct wined3d_blt_fx fx; + DWORD flags = 0; - fx.fill_color = wined3d_format_convert_from_float(surface, color); - return surface_cpu_blt(surface, rect, NULL, &src_rect, - WINED3D_BLT_COLOR_FILL, &fx, WINED3D_TEXF_POINT); + memset(&fx, 0, sizeof(fx)); + switch (op) + { + case WINED3D_BLIT_OP_COLOR_BLIT: + case WINED3D_BLIT_OP_DEPTH_BLIT: + break; + case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST: + flags |= WINED3D_BLT_ALPHA_TEST; + break; + case WINED3D_BLIT_OP_COLOR_BLIT_CKEY: + flags |= WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_FX; + fx.src_color_key = *color_key; + break; + default: + FIXME("Unhandled op %#x.\n", op); + break; + } + + if (FAILED(surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box, + src_texture, src_sub_resource_idx, &src_box, flags, &fx, filter))) + ERR("Failed to blit.\n"); + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); } -static HRESULT cpu_blit_depth_fill(struct wined3d_device *device, - struct wined3d_rendertarget_view *view, const RECT *rect, float depth) +static const struct wined3d_blitter_ops cpu_blitter_ops = { - FIXME("Depth filling not implemented by cpu_blit.\n"); - return WINED3DERR_INVALIDCALL; -} - -static void cpu_blit_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op, DWORD filter, - struct wined3d_surface *src_surface, const RECT *src_rect, - struct wined3d_surface *dst_surface, const RECT *dst_rect, - const struct wined3d_color_key *color_key) -{ - /* FIXME: Remove error returns from surface_blt_cpu. */ - ERR("Blit method not implemented by cpu_blit.\n"); -} - -const struct blit_shader cpu_blit = { - cpu_blit_alloc, - cpu_blit_free, - cpu_blit_set, - cpu_blit_unset, - cpu_blit_supported, - cpu_blit_color_fill, - cpu_blit_depth_fill, - cpu_blit_blit_surface, + cpu_blitter_destroy, + cpu_blitter_clear, + cpu_blitter_blit, }; -#if defined(STAGING_CSMT) -void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect, -#else /* STAGING_CSMT */ +struct wined3d_blitter *wined3d_cpu_blitter_create(void) +{ + struct wined3d_blitter *blitter; + + if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter)))) + return NULL; + + TRACE("Created blitter %p.\n", blitter); + + blitter->ops = &cpu_blitter_ops; + blitter->next = NULL; + + return blitter; +} + HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, -#endif /* STAGING_CSMT */ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { + struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; + struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; + unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); + unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface); + struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource; + struct wined3d_texture *dst_texture = dst_surface->container; + struct wined3d_texture *src_texture = src_surface->container; + struct wined3d_device *device = dst_texture->resource.device; struct wined3d_swapchain *src_swapchain, *dst_swapchain; - struct wined3d_device *device = dst_surface->resource.device; + const struct wined3d_color_key *colour_key = NULL; DWORD src_ds_flags, dst_ds_flags; + struct wined3d_context *context; + enum wined3d_blit_op blit_op; BOOL scale, convert; + DWORD dst_location; - static const DWORD simple_blit = WINED3D_BLT_ASYNC - | WINED3D_BLT_COLOR_FILL - | WINED3D_BLT_SRC_CKEY + static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE - | WINED3D_BLT_WAIT - | WINED3D_BLT_DEPTH_FILL - | WINED3D_BLT_DO_NOT_WAIT | WINED3D_BLT_ALPHA_TEST; -#if !defined(STAGING_CSMT) TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); - TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); + TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage)); if (fx) { TRACE("fx %#x.\n", fx->fx); - TRACE("fill_color 0x%08x.\n", fx->fill_color); TRACE("dst_color_key {0x%08x, 0x%08x}.\n", fx->dst_color_key.color_space_low_value, fx->dst_color_key.color_space_high_value); @@ -5902,50 +3751,9 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst fx->src_color_key.color_space_high_value); } - if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) - { - WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); - return WINEDDERR_SURFACEBUSY; - } - - if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom - || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 - || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 - || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 - || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) - { - WARN("The application gave us a bad destination rectangle.\n"); - return WINEDDERR_INVALIDRECT; - } - - if (src_surface) - { - if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom - || src_rect->left > src_surface->resource.width || src_rect->left < 0 - || src_rect->top > src_surface->resource.height || src_rect->top < 0 - || src_rect->right > src_surface->resource.width || src_rect->right < 0 - || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) - { - WARN("The application gave us a bad source rectangle.\n"); - return WINEDDERR_INVALIDRECT; - } - } - if (!fx || !(fx->fx)) flags &= ~WINED3D_BLT_FX; - if (flags & WINED3D_BLT_WAIT) - flags &= ~WINED3D_BLT_WAIT; - - if (flags & WINED3D_BLT_ASYNC) - { - static unsigned int once; - - if (!once++) - FIXME("Can't handle WINED3D_BLT_ASYNC flag.\n"); - flags &= ~WINED3D_BLT_ASYNC; - } - /* WINED3D_BLT_DO_NOT_WAIT appeared in DX7. */ if (flags & WINED3D_BLT_DO_NOT_WAIT) { @@ -5953,10 +3761,10 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst if (!once++) FIXME("Can't handle WINED3D_BLT_DO_NOT_WAIT flag.\n"); - flags &= ~WINED3D_BLT_DO_NOT_WAIT; } -#endif /* STAGING_CSMT */ + flags &= ~(WINED3D_BLT_SYNCHRONOUS | WINED3D_BLT_DO_NOT_WAIT | WINED3D_BLT_WAIT); + if (!device->d3d_initialized) { WARN("D3D not initialized, using fallback.\n"); @@ -5966,9 +3774,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst /* We want to avoid invalidating the sysmem location for converted * surfaces, since otherwise we'd have to convert the data back when * locking them. */ - if (dst_surface->container->flags & WINED3D_TEXTURE_CONVERTED - || dst_surface->container->resource.format->convert - || wined3d_format_get_color_key_conversion(dst_surface->container, TRUE)) + if (dst_texture->flags & WINED3D_TEXTURE_CONVERTED || dst_texture->resource.format->convert + || wined3d_format_get_color_key_conversion(dst_texture, TRUE)) { WARN_(d3d_perf)("Converted surface, using CPU blit.\n"); goto cpu; @@ -5980,12 +3787,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst goto fallback; } - if (src_surface) - src_swapchain = src_surface->container->swapchain; - else - src_swapchain = NULL; - - dst_swapchain = dst_surface->container->swapchain; + src_swapchain = src_texture->swapchain; + dst_swapchain = dst_texture->swapchain; /* This isn't strictly needed. FBO blits for example could deal with * cross-swapchain blits by first downloading the source to a texture @@ -5998,368 +3801,132 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst goto fallback; } - scale = src_surface - && (src_rect->right - src_rect->left != dst_rect->right - dst_rect->left - || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top); - convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id; + scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left + || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top; + convert = src_texture->resource.format->id != dst_texture->resource.format->id; - dst_ds_flags = dst_surface->container->resource.format_flags + dst_ds_flags = dst_texture->resource.format_flags + & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + src_ds_flags = src_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - if (src_surface) - src_ds_flags = src_surface->container->resource.format_flags - & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - else - src_ds_flags = 0; if (src_ds_flags || dst_ds_flags) { - if (flags & WINED3D_BLT_DEPTH_FILL) - { - float depth; + TRACE("Depth/stencil blit.\n"); - TRACE("Depth fill.\n"); - - if (!surface_convert_depth_to_float(dst_surface, fx->fill_color, &depth)) -#if defined(STAGING_CSMT) - return; - - if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) - return; - } + if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM) + dst_location = dst_texture->resource.map_binding; else - { - if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, - src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) - return; -#else /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; + dst_location = dst_texture->resource.draw_binding; - if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) - return WINED3D_OK; - } - else - { - if (src_ds_flags != dst_ds_flags) - { - WARN("Rejecting depth / stencil blit between incompatible formats.\n"); - return WINED3DERR_INVALIDCALL; - } + context = context_acquire(device, dst_texture, dst_sub_resource_idx); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_DEPTH_BLIT, context, + src_surface, src_texture->resource.draw_binding, src_rect, + dst_surface, dst_location, dst_rect, NULL, filter); + context_release(context); - if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, - src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) - return WINED3D_OK; -#endif /* STAGING_CSMT */ - } + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location); + + return WINED3D_OK; } - else + + TRACE("Colour blit.\n"); + + dst_sub_resource = &dst_texture->sub_resources[dst_sub_resource_idx]; + src_sub_resource = &src_texture->sub_resources[src_sub_resource_idx]; + + /* In principle this would apply to depth blits as well, but we don't + * implement those in the CPU blitter at the moment. */ + if ((dst_sub_resource->locations & dst_texture->resource.map_binding) + && (src_sub_resource->locations & src_texture->resource.map_binding)) { - const struct blit_shader *blitter; + if (scale) + TRACE("Not doing sysmem blit because of scaling.\n"); + else if (convert) + TRACE("Not doing sysmem blit because of format conversion.\n"); + else + goto cpu; + } - /* In principle this would apply to depth blits as well, but we don't - * implement those in the CPU blitter at the moment. */ -#if defined(STAGING_CSMT) - if ((dst_surface->resource.locations & dst_surface->resource.map_binding) - && (!src_surface || (src_surface->resource.locations & src_surface->resource.map_binding))) -#else /* STAGING_CSMT */ - if ((dst_surface->locations & dst_surface->resource.map_binding) - && (!src_surface || (src_surface->locations & src_surface->resource.map_binding))) -#endif /* STAGING_CSMT */ - { - if (scale) - TRACE("Not doing sysmem blit because of scaling.\n"); - else if (convert) - TRACE("Not doing sysmem blit because of format conversion.\n"); - else - goto cpu; - } - - if (flags & WINED3D_BLT_COLOR_FILL) - { - struct wined3d_color color; - const struct wined3d_palette *palette = dst_swapchain ? dst_swapchain->palette : NULL; - - TRACE("Color fill.\n"); - - if (!wined3d_format_convert_color_to_float(dst_surface->resource.format, - palette, fx->fill_color, &color)) - goto fallback; - - if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) -#if defined(STAGING_CSMT) - return; -#else /* STAGING_CSMT */ - return WINED3D_OK; -#endif /* STAGING_CSMT */ - } + blit_op = WINED3D_BLIT_OP_COLOR_BLIT; + if (flags & WINED3D_BLT_SRC_CKEY_OVERRIDE) + { + colour_key = &fx->src_color_key; + blit_op = WINED3D_BLIT_OP_COLOR_BLIT_CKEY; + } + else if (flags & WINED3D_BLT_SRC_CKEY) + { + colour_key = &src_texture->async.src_blt_color_key; + blit_op = WINED3D_BLIT_OP_COLOR_BLIT_CKEY; + } + else if (flags & WINED3D_BLT_ALPHA_TEST) + { + blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; + } + else if ((src_sub_resource->locations & WINED3D_LOCATION_SYSMEM) + && !(dst_sub_resource->locations & WINED3D_LOCATION_SYSMEM)) + { + /* Upload */ + if (scale) + TRACE("Not doing upload because of scaling.\n"); + else if (convert) + TRACE("Not doing upload because of format conversion.\n"); else { - enum wined3d_blit_op blit_op = WINED3D_BLIT_OP_COLOR_BLIT; - const struct wined3d_color_key *color_key = NULL; + POINT dst_point = {dst_rect->left, dst_rect->top}; - TRACE("Color blit.\n"); - if (flags & WINED3D_BLT_SRC_CKEY_OVERRIDE) + if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) { - color_key = &fx->src_color_key; - blit_op = WINED3D_BLIT_OP_COLOR_BLIT_CKEY; - } - else if (flags & WINED3D_BLT_SRC_CKEY) - { - color_key = &src_surface->container->async.src_blt_color_key; - blit_op = WINED3D_BLIT_OP_COLOR_BLIT_CKEY; - } - else if (flags & WINED3D_BLT_ALPHA_TEST) - { - blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; - } -#if defined(STAGING_CSMT) - else if ((src_surface->resource.locations & WINED3D_LOCATION_SYSMEM) - && !(dst_surface->resource.locations & WINED3D_LOCATION_SYSMEM)) -#else /* STAGING_CSMT */ - else if ((src_surface->locations & WINED3D_LOCATION_SYSMEM) - && !(dst_surface->locations & WINED3D_LOCATION_SYSMEM)) -#endif /* STAGING_CSMT */ - { - /* Upload */ - if (scale) - TRACE("Not doing upload because of scaling.\n"); - else if (convert) - TRACE("Not doing upload because of format conversion.\n"); - else + if (!wined3d_resource_is_offscreen(&dst_texture->resource)) { - POINT dst_point = {dst_rect->left, dst_rect->top}; - - if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) - { - if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) - { - struct wined3d_context *context = context_acquire(device, dst_surface); -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&dst_surface->resource, context, - dst_surface->container->resource.draw_binding); - context_release(context); - } - return; -#else /* STAGING_CSMT */ - surface_load_location(dst_surface, context, dst_surface->container->resource.draw_binding); - context_release(context); - } - return WINED3D_OK; -#endif /* STAGING_CSMT */ - } + context = context_acquire(device, dst_texture, dst_sub_resource_idx); + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, + context, dst_texture->resource.draw_binding); + context_release(context); } - } - else if (dst_swapchain && dst_swapchain->back_buffers - && dst_surface->container == dst_swapchain->front_buffer - && src_surface->container == dst_swapchain->back_buffers[0]) - { - /* Use present for back -> front blits. The idea behind this is - * that present is potentially faster than a blit, in particular - * when FBO blits aren't available. Some ddraw applications like - * Half-Life and Prince of Persia 3D use Blt() from the backbuffer - * to the frontbuffer instead of doing a Flip(). D3D8 and D3D9 - * applications can't blit directly to the frontbuffer. */ - enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect; - - TRACE("Using present for backbuffer -> frontbuffer blit.\n"); - - /* Set the swap effect to COPY, we don't want the backbuffer - * to become undefined. */ - dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; - wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0); - dst_swapchain->desc.swap_effect = swap_effect; - -#if defined(STAGING_CSMT) - return; -#else /* STAGING_CSMT */ return WINED3D_OK; -#endif /* STAGING_CSMT */ - } - - if (fbo_blit_supported(&device->adapter->gl_info, blit_op, - src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) - { - struct wined3d_context *context; - TRACE("Using FBO blit.\n"); - - context = context_acquire(device, NULL); - surface_blt_fbo(device, context, filter, - src_surface, src_surface->container->resource.draw_binding, src_rect, - dst_surface, dst_surface->container->resource.draw_binding, dst_rect); - context_release(context); - -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); - - return; -#else /* STAGING_CSMT */ - surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); - surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); - - return WINED3D_OK; -#endif /* STAGING_CSMT */ - } - - blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, - src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); - if (blitter) - { - blitter->blit_surface(device, blit_op, filter, src_surface, - src_rect, dst_surface, dst_rect, color_key); -#if defined(STAGING_CSMT) - return; } } } - -fallback: - /* Special cases for render targets. */ - if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - || (src_surface && (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET))) + else if (dst_swapchain && dst_swapchain->back_buffers + && dst_texture == dst_swapchain->front_buffer + && src_texture == dst_swapchain->back_buffers[0]) { - if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) - return; + /* Use present for back -> front blits. The idea behind this is that + * present is potentially faster than a blit, in particular when FBO + * blits aren't available. Some ddraw applications like Half-Life and + * Prince of Persia 3D use Blt() from the backbuffer to the + * frontbuffer instead of doing a Flip(). D3d8 and d3d9 applications + * can't blit directly to the frontbuffer. */ + enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect; + + TRACE("Using present for backbuffer -> frontbuffer blit.\n"); + + /* Set the swap effect to COPY, we don't want the backbuffer to become + * undefined. */ + dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY; + wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0); + dst_swapchain->desc.swap_effect = swap_effect; + + return WINED3D_OK; } -cpu: - surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); - return; -} + if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM) + dst_location = dst_texture->resource.map_binding; + else + dst_location = dst_texture->resource.draw_binding; -HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) -{ - struct wined3d_device *device = dst_surface->resource.device; + context = context_acquire(device, dst_texture, dst_sub_resource_idx); + device->blitter->ops->blitter_blit(device->blitter, blit_op, context, + src_surface, src_texture->resource.draw_binding, src_rect, + dst_surface, dst_location, dst_rect, colour_key, filter); + context_release(context); - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); - TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); - - if (fx) - { - TRACE("fx %#x.\n", fx->fx); - TRACE("fill_color 0x%08x.\n", fx->fill_color); - TRACE("dst_color_key {0x%08x, 0x%08x}.\n", - fx->dst_color_key.color_space_low_value, - fx->dst_color_key.color_space_high_value); - TRACE("src_color_key {0x%08x, 0x%08x}.\n", - fx->src_color_key.color_space_low_value, - fx->src_color_key.color_space_high_value); - } - - if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) - { - /* TODO: Separate application maps from internal maps */ - if (!wined3d_settings.cs_multithreaded) - { - WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); - return WINEDDERR_SURFACEBUSY; - } - - wined3d_cs_emit_glfinish(dst_surface->resource.device->cs); - dst_surface->resource.device->cs->ops->finish(dst_surface->resource.device->cs); - - if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) - { - WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); - return WINEDDERR_SURFACEBUSY; - } - } - - if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom - || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 - || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 - || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 - || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) - { - WARN("The application gave us a bad destination rectangle.\n"); - return WINEDDERR_INVALIDRECT; - } - - if (src_surface) - { - DWORD src_ds_flags, dst_ds_flags; - - if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom - || src_rect->left > src_surface->resource.width || src_rect->left < 0 - || src_rect->top > src_surface->resource.height || src_rect->top < 0 - || src_rect->right > src_surface->resource.width || src_rect->right < 0 - || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) - { - WARN("The application gave us a bad source rectangle.\n"); - return WINEDDERR_INVALIDRECT; - } - - dst_ds_flags = dst_surface->container->resource.format_flags - & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - src_ds_flags = src_surface->container->resource.format_flags - & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); - if (src_ds_flags != dst_ds_flags) - { - WARN("Rejecting depth / stencil blit between incompatible formats.\n"); - return WINED3DERR_INVALIDCALL; - } - } - - /* FIXME: We should select the blitter in the main thread, that way we can return an error if the blit - * is unsupported without duplicating all the checks... */ - if (flags & WINED3D_BLT_COLOR_FILL && (dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)) - { - WARN("Block color fill, returning WINED3DERR_INVALIDCALL\n"); - return WINED3DERR_INVALIDCALL; - } - - if (!fx || !(fx->fx)) - flags &= ~WINED3D_BLT_FX; - - if (flags & WINED3D_BLT_WAIT) - flags &= ~WINED3D_BLT_WAIT; - - if (flags & WINED3D_BLT_ASYNC) - { - static unsigned int once; - - if (!once++) - FIXME("Can't handle WINED3D_BLT_ASYNC flag.\n"); - flags &= ~WINED3D_BLT_ASYNC; - } - - /* WINEDDBLT_DONOTWAIT appeared in DX7. */ - if (flags & WINED3D_BLT_DO_NOT_WAIT) - { - static unsigned int once; - - if (!once++) - FIXME("Can't handle WINED3D_BLT_DO_NOT_WAIT flag.\n"); - flags &= ~WINED3D_BLT_DO_NOT_WAIT; - } - - TRACE("Emitting blit %p <== %p\n", dst_surface, src_surface); - wined3d_cs_emit_blt(device->cs, dst_surface, dst_rect, src_surface, src_rect, - flags, fx, filter); + wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location); + wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location); return WINED3D_OK; -} - -static const struct wined3d_resource_ops surface_resource_ops = -{ - surface_resource_incref, - surface_resource_decref, - surface_unload, - surface_resource_sub_resource_map, - surface_resource_sub_resource_unmap, - wined3d_surface_location_invalidated, - wined3d_surface_load_location, -}; -#else /* STAGING_CSMT */ - return WINED3D_OK; - } - } - } fallback: /* Special cases for render targets. */ @@ -6367,184 +3934,6 @@ fallback: return WINED3D_OK; cpu: - return surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); -} -#endif /* STAGING_CSMT */ - -static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, - const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags) -{ - struct wined3d_device *device = container->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); - BOOL lockable = flags & WINED3D_TEXTURE_CREATE_MAPPABLE; - UINT multisample_quality = desc->multisample_quality; - unsigned int resource_size; - HRESULT hr; - - /* Quick lockable sanity check. - * TODO: remove this after surfaces, usage and lockability have been debugged properly - * this function is too deep to need to care about things like this. - * Levels need to be checked too, since they all affect what can be done. */ - switch (desc->pool) - { - case WINED3D_POOL_MANAGED: - if (desc->usage & WINED3DUSAGE_DYNAMIC) - FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n"); - break; - - case WINED3D_POOL_DEFAULT: - if (lockable && !(desc->usage & (WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) - WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n"); - break; - - case WINED3D_POOL_SCRATCH: - case WINED3D_POOL_SYSTEM_MEM: - break; - - default: - FIXME("Unknown pool %#x.\n", desc->pool); - break; - }; - - if (desc->usage & WINED3DUSAGE_RENDERTARGET && desc->pool != WINED3D_POOL_DEFAULT) - FIXME("Trying to create a render target that isn't in the default pool.\n"); - - /* FIXME: Check that the format is supported by the device. */ - - resource_size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, 1); - if (!resource_size) - return WINED3DERR_INVALIDCALL; - - if (device->wined3d->flags & WINED3D_NO3D) - surface->surface_ops = &gdi_surface_ops; - else - surface->surface_ops = &surface_ops; - - if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, - format, desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height, - 1, resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops))) - { - WARN("Failed to initialize resource, returning %#x.\n", hr); - return hr; - } - - surface->container = container; -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); -#else /* STAGING_CSMT */ - surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); -#endif /* STAGING_CSMT */ - list_init(&surface->renderbuffers); - list_init(&surface->overlays); - - /* Flags */ - if (flags & WINED3D_TEXTURE_CREATE_DISCARD) - surface->flags |= SFLAG_DISCARD; - if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE) - surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU; - - surface->texture_target = target; - surface->texture_level = level; - surface->texture_layer = layer; - - /* Call the private setup routine */ - if (FAILED(hr = surface->surface_ops->surface_private_setup(surface))) - { - ERR("Private setup failed, hr %#x.\n", hr); - surface_cleanup(surface); - return hr; - } - - /* Similar to lockable rendertargets above, creating the DIB section - * during surface initialization prevents the sysmem pointer from changing - * after a wined3d_texture_get_dc() call. */ - if ((desc->usage & WINED3DUSAGE_OWNDC) && !surface->hDC - && SUCCEEDED(surface_create_dib_section(surface))) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - - if (surface->resource.map_binding == WINED3D_LOCATION_DIB) - { - wined3d_resource_free_sysmem(&surface->resource); -#if defined(STAGING_CSMT) - surface->resource.map_heap_memory = NULL; - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); -#else /* STAGING_CSMT */ - surface_validate_location(surface, WINED3D_LOCATION_DIB); - surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); -#endif /* STAGING_CSMT */ - } - - return hr; -} - -HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - GLenum target, unsigned int level, unsigned int layer, DWORD flags, struct wined3d_surface **surface) -{ - struct wined3d_device_parent *device_parent = container->resource.device->device_parent; - const struct wined3d_parent_ops *parent_ops; - struct wined3d_surface *object; - void *parent; - HRESULT hr; - - TRACE("container %p, width %u, height %u, format %s, usage %s (%#x), pool %s, " - "multisample_type %#x, multisample_quality %u, target %#x, level %u, layer %u, flags %#x, surface %p.\n", - container, desc->width, desc->height, debug_d3dformat(desc->format), - debug_d3dusage(desc->usage), desc->usage, debug_d3dpool(desc->pool), - desc->multisample_type, desc->multisample_quality, target, level, layer, flags, surface); - - if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) - return E_OUTOFMEMORY; - - if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags))) - { - WARN("Failed to initialize surface, returning %#x.\n", hr); -#if defined(STAGING_CSMT) - /* The command stream takes care of freeing the memory. */ -#else /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, object); -#endif /* STAGING_CSMT */ - return hr; - } - - if (FAILED(hr = device_parent->ops->surface_created(device_parent, - container, layer * container->level_count + level, &parent, &parent_ops))) - { - WARN("Failed to create surface parent, hr %#x.\n", hr); - wined3d_surface_destroy(object); - return hr; - } - - TRACE("Created surface %p, parent %p, parent_ops %p.\n", object, parent, parent_ops); - - object->resource.parent = parent; - object->resource.parent_ops = parent_ops; - *surface = object; - - return hr; -} - -/* Context activation is done by the caller. */ -void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) -{ - switch (location) - { - case WINED3D_LOCATION_TEXTURE_RGB: - wined3d_texture_prepare_texture(surface->container, context, FALSE); - break; - - case WINED3D_LOCATION_TEXTURE_SRGB: - wined3d_texture_prepare_texture(surface->container, context, TRUE); - break; - - case WINED3D_LOCATION_RB_MULTISAMPLE: - surface_prepare_rb(surface, context->gl_info, TRUE); - break; - - case WINED3D_LOCATION_RB_RESOLVED: - surface_prepare_rb(surface, context->gl_info, FALSE); - break; - } + return surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box, + src_texture, src_sub_resource_idx, &src_box, flags, fx, filter); } diff --git a/reactos/dll/directx/wine/wined3d/swapchain.c b/reactos/dll/directx/wine/wined3d/swapchain.c index a036a051f9e..53c96a3dce3 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain.c +++ b/reactos/dll/directx/wine/wined3d/swapchain.c @@ -25,6 +25,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); +static void wined3d_swapchain_destroy_object(void *object) +{ + swapchain_destroy_contexts(object); +} + static void swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; @@ -58,11 +63,8 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) swapchain->back_buffers = NULL; } - for (i = 0; i < swapchain->num_contexts; ++i) - { - context_destroy(swapchain->device, swapchain->context[i]); - } - HeapFree(GetProcessHeap(), 0, swapchain->context); + wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain); + swapchain->device->cs->ops->finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); /* Restore the screen resolution if we rendered in fullscreen. * This will restore the screen resolution to what it was before creating @@ -75,6 +77,13 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d, swapchain->device->adapter->ordinal, &swapchain->original_mode))) ERR("Failed to restore display mode, hr %#x.\n", hr); + + if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + { + wined3d_device_restore_fullscreen_window(swapchain->device, swapchain->device_window, + &swapchain->original_window_rect); + wined3d_device_release_focus_window(swapchain->device); + } } if (swapchain->backup_dc) @@ -103,6 +112,10 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) if (!refcount) { + struct wined3d_device *device = swapchain->device; + + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + swapchain_cleanup(swapchain); swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent); HeapFree(GetProcessHeap(), 0, swapchain); @@ -131,14 +144,14 @@ void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWN } HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - const RGNDATA *dirty_region, DWORD flags) + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) { static DWORD notified_flags = 0; + RECT s, d; - TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", + TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n", swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), - dst_window_override, dirty_region, flags); + dst_window_override, flags); if (flags & ~notified_flags) { @@ -152,8 +165,21 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, return WINED3DERR_INVALIDCALL; } + if (!src_rect) + { + SetRect(&s, 0, 0, swapchain->desc.backbuffer_width, + swapchain->desc.backbuffer_height); + src_rect = &s; + } + + if (!dst_rect) + { + GetClientRect(swapchain->win_handle, &d); + dst_rect = &d; + } + wined3d_cs_emit_present(swapchain->device->cs, swapchain, src_rect, - dst_rect, dst_window_override, dirty_region, flags); + dst_rect, dst_window_override, flags); return WINED3D_OK; } @@ -161,19 +187,11 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain, struct wined3d_texture *dst_texture, unsigned int sub_resource_idx) { - struct wined3d_surface *src_surface, *dst_surface; - struct wined3d_resource *sub_resource; RECT src_rect, dst_rect; TRACE("swapchain %p, dst_texture %p, sub_resource_idx %u.\n", swapchain, dst_texture, sub_resource_idx); - if (!(sub_resource = wined3d_texture_get_sub_resource(dst_texture, sub_resource_idx)) || - sub_resource->type != WINED3D_RTYPE_SURFACE) - return WINED3DERR_INVALIDCALL; - - dst_surface = surface_from_resource(sub_resource); - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height); + SetRect(&src_rect, 0, 0, swapchain->front_buffer->resource.width, swapchain->front_buffer->resource.height); dst_rect = src_rect; if (swapchain->desc.windowed) @@ -183,7 +201,8 @@ HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapc wine_dbgstr_rect(&dst_rect)); } - return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT); + return wined3d_texture_blt(dst_texture, sub_resource_idx, &dst_rect, + swapchain->front_buffer, 0, &src_rect, 0, NULL, WINED3D_TEXF_POINT); } struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain, @@ -291,165 +310,90 @@ HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *s static void swapchain_blit(const struct wined3d_swapchain *swapchain, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect) { - struct wined3d_surface *backbuffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); - UINT src_w = src_rect->right - src_rect->left; - UINT src_h = src_rect->bottom - src_rect->top; - GLenum gl_filter; - const struct wined3d_gl_info *gl_info = context->gl_info; - RECT win_rect; - UINT win_h; + struct wined3d_texture *texture = swapchain->back_buffers[0]; + struct wined3d_surface *back_buffer = texture->sub_resources[0].u.surface; + struct wined3d_device *device = swapchain->device; + enum wined3d_texture_filter_type filter; + DWORD location; TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n", swapchain, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect)); - if (src_w == dst_rect->right - dst_rect->left && src_h == dst_rect->bottom - dst_rect->top) - gl_filter = GL_NEAREST; + if ((src_rect->right - src_rect->left == dst_rect->right - dst_rect->left + && src_rect->bottom - src_rect->top == dst_rect->bottom - dst_rect->top) + || is_complex_fixup(texture->resource.format->color_fixup)) + filter = WINED3D_TEXF_NONE; else - gl_filter = GL_LINEAR; + filter = WINED3D_TEXF_LINEAR; - GetClientRect(swapchain->win_handle, &win_rect); - win_h = win_rect.bottom - win_rect.top; + location = WINED3D_LOCATION_TEXTURE_RGB; + if (texture->resource.multisample_type) + location = WINED3D_LOCATION_RB_RESOLVED; - if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format->color_fixup)) - { - DWORD location = WINED3D_LOCATION_TEXTURE_RGB; - - if (backbuffer->resource.multisample_type) - { - location = WINED3D_LOCATION_RB_RESOLVED; -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&backbuffer->resource, context, location); -#else /* STAGING_CSMT */ - surface_load_location(backbuffer, context, location); -#endif /* STAGING_CSMT */ - } - - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); - gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); - context_check_fbo_status(context, GL_READ_FRAMEBUFFER); - - context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)), - NULL, WINED3D_LOCATION_DRAWABLE); - context_set_draw_buffer(context, GL_BACK); - context_invalidate_state(context, STATE_FRAMEBUFFER); - - gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); - - gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); - - /* Note that the texture is upside down */ - gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, - dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom, - GL_COLOR_BUFFER_BIT, gl_filter); - checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n"); - } - else - { - struct wined3d_device *device = swapchain->device; - struct wined3d_context *context2; - float tex_left = src_rect->left; - float tex_top = src_rect->top; - float tex_right = src_rect->right; - float tex_bottom = src_rect->bottom; - - context2 = context_acquire(device, backbuffer); - context_apply_blit_state(context2, device); - - if (backbuffer->container->flags & WINED3D_TEXTURE_NORMALIZED_COORDS) - { - tex_left /= backbuffer->pow2Width; - tex_right /= backbuffer->pow2Width; - tex_top /= backbuffer->pow2Height; - tex_bottom /= backbuffer->pow2Height; - } - - if (is_complex_fixup(backbuffer->resource.format->color_fixup)) - gl_filter = GL_NEAREST; - - context_apply_fbo_state_blit(context2, GL_FRAMEBUFFER, - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)), - NULL, WINED3D_LOCATION_DRAWABLE); - context_bind_texture(context2, backbuffer->texture_target, backbuffer->container->texture_rgb.name); - - /* Set up the texture. The surface is not in a wined3d_texture - * container, so there are no D3D texture settings to dirtify. */ - device->blitter->set_shader(device->blit_priv, context2, backbuffer, NULL); - gl_info->gl_ops.gl.p_glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter); - gl_info->gl_ops.gl.p_glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter); - - context_set_draw_buffer(context, GL_BACK); - - /* Set the viewport to the destination rectandle, disable any projection - * transformation set up by context_apply_blit_state(), and draw a - * (-1,-1)-(1,1) quad. - * - * Back up viewport and matrix to avoid breaking last_was_blit - * - * Note that context_apply_blit_state() set up viewport and ortho to - * match the surface size - we want the GL drawable(=window) size. */ - gl_info->gl_ops.gl.p_glPushAttrib(GL_VIEWPORT_BIT); - gl_info->gl_ops.gl.p_glViewport(dst_rect->left, win_h - dst_rect->bottom, - dst_rect->right, win_h - dst_rect->top); - gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION); - gl_info->gl_ops.gl.p_glPushMatrix(); - gl_info->gl_ops.gl.p_glLoadIdentity(); - - gl_info->gl_ops.gl.p_glBegin(GL_QUADS); - /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(tex_left, tex_bottom); - gl_info->gl_ops.gl.p_glVertex2i(-1, -1); - - /* top left */ - gl_info->gl_ops.gl.p_glTexCoord2f(tex_left, tex_top); - gl_info->gl_ops.gl.p_glVertex2i(-1, 1); - - /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f(tex_right, tex_top); - gl_info->gl_ops.gl.p_glVertex2i(1, 1); - - /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f(tex_right, tex_bottom); - gl_info->gl_ops.gl.p_glVertex2i(1, -1); - gl_info->gl_ops.gl.p_glEnd(); - - gl_info->gl_ops.gl.p_glPopMatrix(); - gl_info->gl_ops.gl.p_glPopAttrib(); - - device->blitter->unset_shader(context->gl_info); - checkGLcall("Swapchain present blit(manual)\n"); - - context_release(context2); - } + wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); + device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer, + location, src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter); + wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE); } -static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, -#if defined(STAGING_CSMT) - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil) +/* Context activation is done by the caller. */ +static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context *context) { - struct wined3d_surface *back_buffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); -#else /* STAGING_CSMT */ - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) + struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_texture *texture, *texture_prev; + struct gl_texture tex0; + GLuint rb0; + DWORD locations0; + unsigned int i; + static const DWORD supported_locations = WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_RB_MULTISAMPLE; + + if (swapchain->desc.backbuffer_count < 2 || !swapchain->render_to_fbo) + return; + + texture_prev = swapchain->back_buffers[0]; + + /* Back buffer 0 is already in the draw binding. */ + tex0 = texture_prev->texture_rgb; + rb0 = texture_prev->rb_multisample; + locations0 = texture_prev->sub_resources[0].locations; + + for (i = 1; i < swapchain->desc.backbuffer_count; ++i) + { + texture = swapchain->back_buffers[i]; + sub_resource = &texture->sub_resources[0]; + + if (!(sub_resource->locations & supported_locations)) + wined3d_texture_load_location(texture, 0, context, texture->resource.draw_binding); + + texture_prev->texture_rgb = texture->texture_rgb; + texture_prev->rb_multisample = texture->rb_multisample; + + wined3d_texture_validate_location(texture_prev, 0, sub_resource->locations & supported_locations); + wined3d_texture_invalidate_location(texture_prev, 0, ~(sub_resource->locations & supported_locations)); + + texture_prev = texture; + } + + texture_prev->texture_rgb = tex0; + texture_prev->rb_multisample = rb0; + + wined3d_texture_validate_location(texture_prev, 0, locations0 & supported_locations); + wined3d_texture_invalidate_location(texture_prev, 0, ~(locations0 & supported_locations)); + + device_invalidate_state(swapchain->device, STATE_FRAMEBUFFER); +} + +static void swapchain_gl_present(struct wined3d_swapchain *swapchain, + const RECT *src_rect, const RECT *dst_rect, DWORD flags) { - struct wined3d_surface *back_buffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); - const struct wined3d_fb_state *fb = &swapchain->device->fb; -#endif /* STAGING_CSMT */ + struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; + const struct wined3d_fb_state *fb = &swapchain->device->cs->fb; const struct wined3d_gl_info *gl_info; + struct wined3d_texture *logo_texture; struct wined3d_context *context; - struct wined3d_surface *front; - RECT src_rect, dst_rect; BOOL render_to_fbo; - context = context_acquire(swapchain->device, back_buffer); + context = context_acquire(swapchain->device, back_buffer, 0); if (!context->valid) { context_release(context); @@ -459,24 +403,19 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT gl_info = context->gl_info; - if (swapchain->device->logo_texture) + if ((logo_texture = swapchain->device->logo_texture)) { - struct wined3d_surface *src_surface = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->device->logo_texture, 0)); - RECT rect = {0, 0, src_surface->resource.width, src_surface->resource.height}; + RECT rect = {0, 0, logo_texture->resource.width, logo_texture->resource.height}; /* Blit the logo into the upper left corner of the drawable. */ - wined3d_surface_blt(back_buffer, &rect, src_surface, &rect, - WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT); + wined3d_texture_blt(back_buffer, 0, &rect, logo_texture, 0, &rect, + WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT); } -#if !defined(STAGING_CSMT) if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture && !swapchain->device->hardwareCursor) { - struct wined3d_surface *cursor = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); - RECT destRect = + RECT dst_rect = { swapchain->device->xScreenSpace - swapchain->device->xHotSpot, swapchain->device->yScreenSpace - swapchain->device->yHotSpot, @@ -494,43 +433,22 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT TRACE("Rendering the software cursor.\n"); if (swapchain->desc.windowed) - MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); - if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect)) - wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, + MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2); + if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect)) + wined3d_texture_blt(back_buffer, 0, &dst_rect, + swapchain->device->cursor_texture, 0, &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT); } -#endif /* STAGING_CSMT */ TRACE("Presenting HDC %p.\n", context->hdc); - render_to_fbo = swapchain->render_to_fbo; - - if (src_rect_in) - { - src_rect = *src_rect_in; - if (!render_to_fbo && (src_rect.left || src_rect.top - || src_rect.right != swapchain->desc.backbuffer_width - || src_rect.bottom != swapchain->desc.backbuffer_height)) - { - render_to_fbo = TRUE; - } - } - else - { - src_rect.left = 0; - src_rect.top = 0; - src_rect.right = swapchain->desc.backbuffer_width; - src_rect.bottom = swapchain->desc.backbuffer_height; - } - - if (dst_rect_in) - dst_rect = *dst_rect_in; - else - GetClientRect(swapchain->win_handle, &dst_rect); - - if (!render_to_fbo && (dst_rect.left || dst_rect.top - || dst_rect.right != swapchain->desc.backbuffer_width - || dst_rect.bottom != swapchain->desc.backbuffer_height)) + if (!(render_to_fbo = swapchain->render_to_fbo) + && (src_rect->left || src_rect->top + || src_rect->right != swapchain->desc.backbuffer_width + || src_rect->bottom != swapchain->desc.backbuffer_height + || dst_rect->left || dst_rect->top + || dst_rect->right != swapchain->desc.backbuffer_width + || dst_rect->bottom != swapchain->desc.backbuffer_height)) render_to_fbo = TRUE; /* Rendering to a window of different size, presenting partial rectangles, @@ -542,25 +460,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT */ if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&back_buffer->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&back_buffer->resource, WINED3D_LOCATION_DRAWABLE); + wined3d_texture_load_location(back_buffer, 0, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_invalidate_location(back_buffer, 0, WINED3D_LOCATION_DRAWABLE); swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); } else { - wined3d_resource_load_location(&back_buffer->resource, context, back_buffer->container->resource.draw_binding); -#else /* STAGING_CSMT */ - surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB); - surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE); - swapchain->render_to_fbo = TRUE; - swapchain_update_draw_bindings(swapchain); - } - else - { - surface_load_location(back_buffer, context, back_buffer->container->resource.draw_binding); -#endif /* STAGING_CSMT */ + wined3d_texture_load_location(back_buffer, 0, context, back_buffer->resource.draw_binding); } if (swapchain->render_to_fbo) @@ -570,19 +477,20 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP && !once++) FIXME("WINED3D_SWAP_EFFECT_FLIP not implemented.\n"); - swapchain_blit(swapchain, context, &src_rect, &dst_rect); + swapchain_blit(swapchain, context, src_rect, dst_rect); } -#if defined(STAGING_CSMT) - if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFlush(); -#else /* STAGING_CSMT */ +#if !defined(STAGING_CSMT) if (swapchain->num_contexts > 1) - gl_info->gl_ops.gl.p_glFinish(); +#else /* STAGING_CSMT */ + if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) #endif /* STAGING_CSMT */ + gl_info->gl_ops.gl.p_glFinish(); /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ - gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */ + gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); + + wined3d_swapchain_rotate(swapchain, context); TRACE("SwapBuffers called, Starting new frame\n"); /* FPS support */ @@ -601,40 +509,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT } } - front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&front->resource, WINED3D_LOCATION_DRAWABLE); - wined3d_resource_invalidate_location(&front->resource, ~WINED3D_LOCATION_DRAWABLE); - switch (swapchain->desc.swap_effect) - { - case WINED3D_SWAP_EFFECT_DISCARD: - wined3d_resource_validate_location(&back_buffer->resource, WINED3D_LOCATION_DISCARDED); - break; - - case WINED3D_SWAP_EFFECT_FLIP: - wined3d_resource_validate_location(&back_buffer->resource, back_buffer->container->resource.draw_binding); - wined3d_resource_invalidate_location(&back_buffer->resource, ~back_buffer->container->resource.draw_binding); - break; - - default: - break; - } - - if (depth_stencil) - { - if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || depth_stencil->flags & SFLAG_DISCARD) - { - surface_modify_ds_location(depth_stencil, WINED3D_LOCATION_DISCARDED, - depth_stencil->resource.width, depth_stencil->resource.height); - if (depth_stencil == swapchain->device->cs->onscreen_depth_stencil) - { - wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container); - swapchain->device->cs->onscreen_depth_stencil = NULL; -#else /* STAGING_CSMT */ - surface_validate_location(front, WINED3D_LOCATION_DRAWABLE); - surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE); + wined3d_texture_validate_location(swapchain->front_buffer, 0, WINED3D_LOCATION_DRAWABLE); + wined3d_texture_invalidate_location(swapchain->front_buffer, 0, ~WINED3D_LOCATION_DRAWABLE); /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. * If the swapeffect is COPY, the content remains the same. @@ -642,35 +518,41 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE * up to date and hope WGL flipped front and back buffers and read this data into * the FBO. Don't bother about this for now. */ + if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD) + wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1], + 0, WINED3D_LOCATION_DISCARDED); if (fb->depth_stencil) { struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); - if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ds->flags & SFLAG_DISCARD)) - { - surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED, - fb->depth_stencil->width, fb->depth_stencil->height); - if (ds == swapchain->device->onscreen_depth_stencil) - { - wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); - swapchain->device->onscreen_depth_stencil = NULL; -#endif /* STAGING_CSMT */ - } - } + if (ds && (swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL + || ds->container->flags & WINED3D_TEXTURE_DISCARD)) + wined3d_texture_validate_location(ds->container, + fb->depth_stencil->sub_resource_idx, WINED3D_LOCATION_DISCARDED); } context_release(context); } +static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain) +{ + struct wined3d_texture *front_buffer = swapchain->front_buffer; + struct wined3d_context *context; + + context = context_acquire(swapchain->device, front_buffer, 0); + wined3d_texture_load_location(front_buffer, 0, context, front_buffer->resource.draw_binding); + context_release(context); + SetRectEmpty(&swapchain->front_buffer_update); +} + static const struct wined3d_swapchain_ops swapchain_gl_ops = { swapchain_gl_present, + swapchain_gl_frontbuffer_updated, }; -/* Helper function that blits the front buffer contents to the target window. */ -void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) +static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain) { struct wined3d_surface *front; POINT offset = {0, 0}; @@ -678,24 +560,18 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r RECT draw_rect; HWND window; - TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); + TRACE("swapchain %p.\n", swapchain); - front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); + front = swapchain->front_buffer->sub_resources[0].u.surface; if (swapchain->palette) - wined3d_palette_apply_to_dc(swapchain->palette, front->hDC); + wined3d_palette_apply_to_dc(swapchain->palette, front->dc); - if (front->resource.map_count) + if (front->container->resource.map_count) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&front->resource, NULL, WINED3D_LOCATION_DIB); -#else /* STAGING_CSMT */ - surface_load_location(front, NULL, WINED3D_LOCATION_DIB); -#endif /* STAGING_CSMT */ - - src_dc = front->hDC; + src_dc = front->dc; window = swapchain->win_handle; dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); @@ -706,69 +582,41 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r TRACE("offset %s.\n", wine_dbgstr_point(&offset)); - draw_rect.left = 0; - draw_rect.right = front->resource.width; - draw_rect.top = 0; - draw_rect.bottom = front->resource.height; - - if (rect) - IntersectRect(&draw_rect, &draw_rect, rect); + SetRect(&draw_rect, 0, 0, swapchain->front_buffer->resource.width, + swapchain->front_buffer->resource.height); + IntersectRect(&draw_rect, &draw_rect, &swapchain->front_buffer_update); BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y, draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top, src_dc, draw_rect.left, draw_rect.top, SRCCOPY); ReleaseDC(window, dst_dc); + + SetRectEmpty(&swapchain->front_buffer_update); } -static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, -#if defined(STAGING_CSMT) - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil) -#else /* STAGING_CSMT */ - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) -#endif /* STAGING_CSMT */ +static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, + const RECT *src_rect, const RECT *dst_rect, DWORD flags) { struct wined3d_surface *front, *back; + HBITMAP bitmap; + void *data; + HDC dc; - front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - back = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); - - /* Flip the DC. */ - { - HDC tmp; - tmp = front->hDC; - front->hDC = back->hDC; - back->hDC = tmp; - } - - /* Flip the DIBsection. */ - { - HBITMAP tmp; - tmp = front->dib.DIBsection; - front->dib.DIBsection = back->dib.DIBsection; - back->dib.DIBsection = tmp; - } + front = swapchain->front_buffer->sub_resources[0].u.surface; + back = swapchain->back_buffers[0]->sub_resources[0].u.surface; /* Flip the surface data. */ - { - void *tmp; + dc = front->dc; + bitmap = front->bitmap; + data = front->container->resource.heap_memory; -#if defined(STAGING_CSMT) - tmp = front->resource.bitmap_data; - front->resource.bitmap_data = back->resource.bitmap_data; - back->resource.bitmap_data = tmp; -#else /* STAGING_CSMT */ - tmp = front->dib.bitmap_data; - front->dib.bitmap_data = back->dib.bitmap_data; - back->dib.bitmap_data = tmp; -#endif /* STAGING_CSMT */ + front->dc = back->dc; + front->bitmap = back->bitmap; + front->container->resource.heap_memory = back->container->resource.heap_memory; - if (front->resource.heap_memory) - ERR("GDI Surface %p has heap memory allocated.\n", front); - - if (back->resource.heap_memory) - ERR("GDI Surface %p has heap memory allocated.\n", back); - } + back->dc = dc; + back->bitmap = bitmap; + back->container->resource.heap_memory = data; /* FPS support */ if (TRACE_ON(fps)) @@ -787,18 +635,20 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const REC } } - x11_copy_to_screen(swapchain, NULL); + SetRect(&swapchain->front_buffer_update, 0, 0, + swapchain->front_buffer->resource.width, + swapchain->front_buffer->resource.height); + swapchain_gdi_frontbuffer_updated(swapchain); } static const struct wined3d_swapchain_ops swapchain_gdi_ops = { swapchain_gdi_present, + swapchain_gdi_frontbuffer_updated, }; static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) { - RECT client_rect; - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; @@ -809,101 +659,126 @@ static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) return; } - GetClientRect(swapchain->win_handle, &client_rect); - - TRACE("Backbuffer %ux%u, window %ux%u.\n", - swapchain->desc.backbuffer_width, - swapchain->desc.backbuffer_height, - client_rect.right, client_rect.bottom); - TRACE("Multisample type %#x, quality %#x.\n", - swapchain->desc.multisample_type, - swapchain->desc.multisample_quality); - - if (!wined3d_settings.always_offscreen && !swapchain->desc.multisample_type - && swapchain->desc.backbuffer_width == client_rect.right - && swapchain->desc.backbuffer_height == client_rect.bottom) - { - TRACE("Backbuffer dimensions match window dimensions, rendering onscreen.\n"); - swapchain->render_to_fbo = FALSE; - return; - } - TRACE("Rendering to FBO.\n"); swapchain->render_to_fbo = TRUE; } -#if defined(STAGING_CSMT) -HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +static void wined3d_swapchain_apply_sample_count_override(const struct wined3d_swapchain *swapchain, + enum wined3d_format_id format_id, enum wined3d_multisample_type *type, DWORD *quality) { - const struct wined3d_adapter *adapter = device->adapter; + const struct wined3d_gl_info *gl_info; + const struct wined3d_format *format; + enum wined3d_multisample_type t; + + if (wined3d_settings.sample_count == ~0u) + return; + + gl_info = &swapchain->device->adapter->gl_info; + if (!(format = wined3d_get_format(gl_info, format_id, WINED3DUSAGE_RENDERTARGET))) + return; + + if ((t = min(wined3d_settings.sample_count, gl_info->limits.samples))) + while (!(format->multisample_types & 1u << (t - 1))) + ++t; + TRACE("Using sample count %u.\n", t); + *type = t; + *quality = 0; +} + +static void wined3d_swapchain_update_swap_interval_cs(void *object) +{ + struct wined3d_swapchain *swapchain = object; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + int swap_interval; + + context = context_acquire(swapchain->device, swapchain->front_buffer, 0); + gl_info = context->gl_info; + + switch (swapchain->desc.swap_interval) + { + case WINED3DPRESENT_INTERVAL_IMMEDIATE: + swap_interval = 0; + break; + case WINED3DPRESENT_INTERVAL_DEFAULT: + case WINED3DPRESENT_INTERVAL_ONE: + swap_interval = 1; + break; + case WINED3DPRESENT_INTERVAL_TWO: + swap_interval = 2; + break; + case WINED3DPRESENT_INTERVAL_THREE: + swap_interval = 3; + break; + case WINED3DPRESENT_INTERVAL_FOUR: + swap_interval = 4; + break; + default: + FIXME("Unhandled present interval %#x.\n", swapchain->desc.swap_interval); + swap_interval = 1; + } + + if (gl_info->supported[WGL_EXT_SWAP_CONTROL]) + { + if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval))) + ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n", + swap_interval, context, GetLastError()); + } + + context_release(context); +} + +static void wined3d_swapchain_cs_init(void *object) +{ + struct wined3d_swapchain *swapchain = object; + const struct wined3d_gl_info *gl_info; unsigned int i; + static const enum wined3d_format_id formats[] = { WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_D32_UNORM, WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_D16_UNORM, - WINED3DFMT_S1_UINT_D15_UNORM + WINED3DFMT_S1_UINT_D15_UNORM, }; - struct wined3d_surface *front_buffer; - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); - if (!swapchain->context) - { - ERR("Failed to create the context array.\n"); - return E_OUTOFMEMORY; - } - swapchain->num_contexts = 1; + gl_info = &swapchain->device->adapter->gl_info; - /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. - * You are able to add a depth + stencil surface at a later stage when you need it. - * In order to support this properly in WineD3D we need the ability to recreate the opengl context and - * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new - * context, need torecreate shaders, textures and other resources. - * - * The context manager already takes care of the state problem and for the other tasks code from Reset - * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. - * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the - * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this - * issue needs to be fixed. */ - front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) + /* Without ORM_FBO, switching the depth/stencil format is hard. Always + * request a depth/stencil buffer in the likely case it's needed later. */ + for (i = 0; i < ARRAY_SIZE(formats); ++i) { - swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); - swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); - if (swapchain->context[0]) break; - TRACE("Depth stencil format %s is not supported, trying next format\n", - debug_d3dformat(formats[i])); + swapchain->ds_format = wined3d_get_format(gl_info, formats[i], WINED3DUSAGE_DEPTHSTENCIL); + if ((swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format))) + break; + TRACE("Depth stencil format %s is not supported, trying next format.\n", debug_d3dformat(formats[i])); } if (!swapchain->context[0]) { WARN("Failed to create context.\n"); - HeapFree(GetProcessHeap(), 0, swapchain->context); - swapchain->context = NULL; - return WINED3DERR_NOTAVAILABLE; + return; } + swapchain->num_contexts = 1; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && (!swapchain->desc.enable_auto_depth_stencil || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) - { - FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); - } + FIXME("Add OpenGL context recreation support.\n"); + context_release(swapchain->context[0]); - return WINED3D_OK; + wined3d_swapchain_update_swap_interval_cs(swapchain); } -#endif /* STAGING_CSMT */ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_adapter *adapter = device->adapter; struct wined3d_resource_desc texture_desc; - struct wined3d_surface *front_buffer; BOOL displaymode_set = FALSE; + DWORD texture_flags = 0; RECT client_rect; HWND window; HRESULT hr; @@ -935,13 +810,11 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 ERR("Failed to get current display mode, hr %#x.\n", hr); goto err; } + GetWindowRect(window, &swapchain->original_window_rect); GetClientRect(window, &client_rect); - if (desc->windowed - && (!desc->backbuffer_width || !desc->backbuffer_height - || desc->backbuffer_format == WINED3DFMT_UNKNOWN)) + if (desc->windowed) { - if (!desc->backbuffer_width) { desc->backbuffer_width = client_rect.right; @@ -961,6 +834,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 } } swapchain->desc = *desc; + wined3d_swapchain_apply_sample_count_override(swapchain, swapchain->desc.backbuffer_format, + &swapchain->desc.multisample_type, &swapchain->desc.multisample_quality); swapchain_update_render_to_fbo(swapchain); TRACE("Creating front buffer.\n"); @@ -976,65 +851,53 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 texture_desc.depth = 1; texture_desc.size = 0; + if (swapchain->desc.flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - parent, &texture_desc, &swapchain->front_buffer))) + parent, &texture_desc, texture_flags, &swapchain->front_buffer))) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } wined3d_texture_set_swapchain(swapchain->front_buffer, swapchain); - front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); if (!(device->wined3d->flags & WINED3D_NO3D)) { -#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&front_buffer->resource, WINED3D_LOCATION_DRAWABLE); - wined3d_resource_invalidate_location(&front_buffer->resource, ~WINED3D_LOCATION_DRAWABLE); -#else /* STAGING_CSMT */ - surface_validate_location(front_buffer, WINED3D_LOCATION_DRAWABLE); - surface_invalidate_location(front_buffer, ~WINED3D_LOCATION_DRAWABLE); -#endif /* STAGING_CSMT */ + wined3d_texture_validate_location(swapchain->front_buffer, 0, WINED3D_LOCATION_DRAWABLE); + wined3d_texture_invalidate_location(swapchain->front_buffer, 0, ~WINED3D_LOCATION_DRAWABLE); } /* MSDN says we're only allowed a single fullscreen swapchain per device, * so we should really check to see if there is a fullscreen swapchain * already. Does a single head count as full screen? */ - if (!desc->windowed) { - /* Change the display settings */ - swapchain->d3d_mode.width = desc->backbuffer_width; - swapchain->d3d_mode.height = desc->backbuffer_height; - swapchain->d3d_mode.format_id = desc->backbuffer_format; - swapchain->d3d_mode.refresh_rate = desc->refresh_rate; - swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; - - if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->d3d_mode))) + if (desc->flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { - WARN("Failed to set display mode, hr %#x.\n", hr); - goto err; + /* Change the display settings */ + swapchain->d3d_mode.width = desc->backbuffer_width; + swapchain->d3d_mode.height = desc->backbuffer_height; + swapchain->d3d_mode.format_id = desc->backbuffer_format; + swapchain->d3d_mode.refresh_rate = desc->refresh_rate; + swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; + + if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, + adapter->ordinal, &swapchain->d3d_mode))) + { + WARN("Failed to set display mode, hr %#x.\n", hr); + goto err; + } + displaymode_set = TRUE; + } + else + { + swapchain->d3d_mode = swapchain->original_mode; } - displaymode_set = TRUE; } if (!(device->wined3d->flags & WINED3D_NO3D)) { -#if defined(STAGING_CSMT) - hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); - if (FAILED(hr)) - goto err; -#else /* STAGING_CSMT */ - static const enum wined3d_format_id formats[] = - { - WINED3DFMT_D24_UNORM_S8_UINT, - WINED3DFMT_D32_UNORM, - WINED3DFMT_R24_UNORM_X8_TYPELESS, - WINED3DFMT_D16_UNORM, - WINED3DFMT_S1_UINT_D15_UNORM - }; - - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); if (!swapchain->context) { @@ -1042,50 +905,21 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 hr = E_OUTOFMEMORY; goto err; } - swapchain->num_contexts = 1; - /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. - * You are able to add a depth + stencil surface at a later stage when you need it. - * In order to support this properly in WineD3D we need the ability to recreate the opengl context and - * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new - * context, need torecreate shaders, textures and other resources. - * - * The context manager already takes care of the state problem and for the other tasks code from Reset - * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. - * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the - * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this - * issue needs to be fixed. */ - for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) - { - swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); - swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); - if (swapchain->context[0]) break; - TRACE("Depth stencil format %s is not supported, trying next format\n", - debug_d3dformat(formats[i])); - } + wined3d_cs_init_object(device->cs, wined3d_swapchain_cs_init, swapchain); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); if (!swapchain->context[0]) { - WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } - - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && (!desc->enable_auto_depth_stencil - || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) - { - FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); - } - context_release(swapchain->context[0]); -#endif /* STAGING_CSMT */ } if (swapchain->desc.backbuffer_count > 0) { - swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0, - sizeof(*swapchain->back_buffers) * swapchain->desc.backbuffer_count); - if (!swapchain->back_buffers) + if (!(swapchain->back_buffers = wined3d_calloc(swapchain->desc.backbuffer_count, + sizeof(*swapchain->back_buffers)))) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; @@ -1097,7 +931,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 { TRACE("Creating back buffer %u.\n", i); if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - parent, &texture_desc, &swapchain->back_buffers[i]))) + parent, &texture_desc, texture_flags, &swapchain->back_buffers[i]))) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); swapchain->desc.backbuffer_count = i; @@ -1113,21 +947,23 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 TRACE("Creating depth/stencil buffer.\n"); if (!device->auto_depth_stencil_view) { + struct wined3d_view_desc desc; struct wined3d_texture *ds; - struct wined3d_rendertarget_view_desc desc; texture_desc.format = swapchain->desc.auto_depth_stencil_format; texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL; if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, - device->device_parent, &texture_desc, &ds))) + device->device_parent, &texture_desc, texture_flags, &ds))) { WARN("Failed to create the auto depth/stencil surface, hr %#x.\n", hr); goto err; } desc.format_id = ds->resource.format->id; + desc.flags = 0; desc.u.texture.level_idx = 0; + desc.u.texture.level_count = 1; desc.u.texture.layer_idx = 0; desc.u.texture.layer_count = 1; hr = wined3d_rendertarget_view_create(&desc, &ds->resource, NULL, &wined3d_null_parent_ops, @@ -1167,16 +1003,8 @@ err: HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); } - if (swapchain->context) - { - if (swapchain->context[0]) - { - context_release(swapchain->context[0]); - context_destroy(device, swapchain->context[0]); - swapchain->num_contexts = 0; - } - HeapFree(GetProcessHeap(), 0, swapchain->context); - } + wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain); + swapchain->device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); if (swapchain->front_buffer) { @@ -1216,30 +1044,28 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) { - struct wined3d_context **newArray; + struct wined3d_context **ctx_array; struct wined3d_context *ctx; TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain, GetCurrentThreadId()); - if (!(ctx = context_create(swapchain, - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)), - swapchain->ds_format))) + if (!(ctx = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format))) { ERR("Failed to create a new context for the swapchain\n"); return NULL; } context_release(ctx); - newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * (swapchain->num_contexts + 1)); - if(!newArray) { + if (!(ctx_array = wined3d_calloc(swapchain->num_contexts + 1, sizeof(*ctx_array)))) + { ERR("Out of memory when trying to allocate a new context array\n"); context_destroy(swapchain->device, ctx); return NULL; } - memcpy(newArray, swapchain->context, sizeof(*newArray) * swapchain->num_contexts); + memcpy(ctx_array, swapchain->context, sizeof(*ctx_array) * swapchain->num_contexts); HeapFree(GetProcessHeap(), 0, swapchain->context); - newArray[swapchain->num_contexts] = ctx; - swapchain->context = newArray; + ctx_array[swapchain->num_contexts] = ctx; + swapchain->context = ctx_array; swapchain->num_contexts++; TRACE("Returning context %p\n", ctx); @@ -1254,7 +1080,9 @@ void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) { context_destroy(swapchain->device, swapchain->context[i]); } + HeapFree(GetProcessHeap(), 0, swapchain->context); swapchain->num_contexts = 0; + swapchain->context = NULL; } struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) @@ -1309,6 +1137,11 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) } } +void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) +{ + wined3d_cs_init_object(swapchain->device->cs, wined3d_swapchain_update_swap_interval_cs, swapchain); +} + void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) { struct wined3d_device *device = swapchain->device; @@ -1364,6 +1197,7 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality) { + struct wined3d_device *device = swapchain->device; BOOL update_desc = FALSE; TRACE("swapchain %p, buffer_count %u, width %u, height %u, format %s, " @@ -1371,9 +1205,13 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha swapchain, buffer_count, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality); + wined3d_swapchain_apply_sample_count_override(swapchain, format_id, &multisample_type, &multisample_quality); + if (buffer_count && buffer_count != swapchain->desc.backbuffer_count) FIXME("Cannot change the back buffer count yet.\n"); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!width || !height) { /* The application is requesting that either the swapchain width or @@ -1451,3 +1289,168 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha return WINED3D_OK; } + +static HRESULT wined3d_swapchain_set_display_mode(struct wined3d_swapchain *swapchain, + struct wined3d_display_mode *mode) +{ + struct wined3d_device *device = swapchain->device; + HRESULT hr; + + if (swapchain->desc.flags & WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE) + { + if (FAILED(hr = wined3d_find_closest_matching_adapter_mode(device->wined3d, + device->adapter->ordinal, mode))) + { + WARN("Failed to find closest matching mode, hr %#x.\n", hr); + } + } + + if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, + device->adapter->ordinal, mode))) + { + WARN("Failed to set display mode, hr %#x.\n", hr); + return WINED3DERR_INVALIDCALL; + } + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, + const struct wined3d_display_mode *mode) +{ + struct wined3d_device *device = swapchain->device; + struct wined3d_display_mode actual_mode; + RECT original_window_rect, window_rect; + HRESULT hr; + + TRACE("swapchain %p, mode %p.\n", swapchain, mode); + + if (swapchain->desc.windowed) + { + SetRect(&window_rect, 0, 0, mode->width, mode->height); + AdjustWindowRectEx(&window_rect, + GetWindowLongW(swapchain->device_window, GWL_STYLE), FALSE, + GetWindowLongW(swapchain->device_window, GWL_EXSTYLE)); + SetRect(&window_rect, 0, 0, + window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); + GetWindowRect(swapchain->device_window, &original_window_rect); + OffsetRect(&window_rect, original_window_rect.left, original_window_rect.top); + } + else if (swapchain->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + { + actual_mode = *mode; + if (FAILED(hr = wined3d_swapchain_set_display_mode(swapchain, &actual_mode))) + return hr; + SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); + } + else + { + if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, + &actual_mode, NULL))) + { + ERR("Failed to get display mode, hr %#x.\n", hr); + return WINED3DERR_INVALIDCALL; + } + + SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); + } + + MoveWindow(swapchain->device_window, window_rect.left, window_rect.top, + window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top, TRUE); + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, + const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode) +{ + struct wined3d_device *device = swapchain->device; + struct wined3d_display_mode actual_mode; + HRESULT hr; + + TRACE("swapchain %p, desc %p, mode %p.\n", swapchain, swapchain_desc, mode); + + if (swapchain->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) + { + if (mode) + { + actual_mode = *mode; + } + else + { + if (!swapchain_desc->windowed) + { + actual_mode.width = swapchain_desc->backbuffer_width; + actual_mode.height = swapchain_desc->backbuffer_height; + actual_mode.refresh_rate = swapchain_desc->refresh_rate; + actual_mode.format_id = swapchain_desc->backbuffer_format; + actual_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; + } + else + { + actual_mode = swapchain->original_mode; + } + } + + if (FAILED(hr = wined3d_swapchain_set_display_mode(swapchain, &actual_mode))) + return hr; + } + else + { + if (mode) + WARN("WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH is not set, ignoring mode.\n"); + + if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, + &actual_mode, NULL))) + { + ERR("Failed to get display mode, hr %#x.\n", hr); + return WINED3DERR_INVALIDCALL; + } + } + + if (!swapchain_desc->windowed) + { + unsigned int width = actual_mode.width; + unsigned int height = actual_mode.height; + + if (swapchain->desc.windowed) + { + /* Switch from windowed to fullscreen */ + HWND focus_window = device->create_parms.focus_window; + if (!focus_window) + focus_window = swapchain->device_window; + if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + return hr; + } + + wined3d_device_setup_fullscreen_window(device, swapchain->device_window, width, height); + } + else + { + /* Fullscreen -> fullscreen mode change */ + BOOL filter_messages = device->filter_messages; + device->filter_messages = TRUE; + + MoveWindow(swapchain->device_window, 0, 0, width, height, TRUE); + + device->filter_messages = filter_messages; + } + swapchain->d3d_mode = actual_mode; + } + else if (!swapchain->desc.windowed) + { + /* Fullscreen -> windowed switch */ + RECT *window_rect = NULL; + if (swapchain->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + window_rect = &swapchain->original_window_rect; + wined3d_device_restore_fullscreen_window(device, swapchain->device_window, window_rect); + wined3d_device_release_focus_window(device); + } + + swapchain->desc.windowed = swapchain_desc->windowed; + + return WINED3D_OK; +} diff --git a/reactos/dll/directx/wine/wined3d/texture.c b/reactos/dll/directx/wine/wined3d/texture.c index a7195d85515..70c54a255d8 100644 --- a/reactos/dll/directx/wine/wined3d/texture.c +++ b/reactos/dll/directx/wine/wined3d/texture.c @@ -22,15 +22,309 @@ #include "wined3d_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture); +WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(winediag); +#define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50 + +static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info) +{ + return texture->resource.pool == WINED3D_POOL_DEFAULT + && texture->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU + && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] + && !texture->resource.format->convert + && !(texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED)); +} + +static BOOL wined3d_texture_use_immutable_storage(const struct wined3d_texture *texture, + const struct wined3d_gl_info *gl_info) +{ + /* We don't expect to create texture views for textures with height-scaled formats. + * Besides, ARB_texture_storage doesn't allow specifying exact sizes for all levels. */ + return gl_info->supported[ARB_TEXTURE_STORAGE] + && !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE); +} + +GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) +{ + const struct wined3d_swapchain *swapchain = texture->swapchain; + + TRACE("texture %p.\n", texture); + + if (!swapchain) + { + ERR("Texture %p is not part of a swapchain.\n", texture); + return GL_NONE; + } + + if (texture == swapchain->front_buffer) + { + TRACE("Returning GL_FRONT.\n"); + return GL_FRONT; + } + + if (texture == swapchain->back_buffers[0]) + { + TRACE("Returning GL_BACK.\n"); + return GL_BACK; + } + + FIXME("Higher back buffer, returning GL_BACK.\n"); + return GL_BACK; +} + +static DWORD wined3d_resource_access_from_location(DWORD location) +{ + switch (location) + { + case WINED3D_LOCATION_DISCARDED: + return 0; + + case WINED3D_LOCATION_SYSMEM: + case WINED3D_LOCATION_USER_MEMORY: + return WINED3D_RESOURCE_ACCESS_CPU; + + case WINED3D_LOCATION_BUFFER: + case WINED3D_LOCATION_DRAWABLE: + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + case WINED3D_LOCATION_RB_MULTISAMPLE: + case WINED3D_LOCATION_RB_RESOLVED: + return WINED3D_RESOURCE_ACCESS_GPU; + + default: + FIXME("Unhandled location %#x.\n", location); + return 0; + } +} + +static BOOL is_power_of_two(UINT x) +{ + return (x != 0) && !(x & (x - 1)); +} + +static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture) +{ + struct wined3d_texture_sub_resource *sub_resource; + unsigned int i, sub_count; + + if (texture->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM) + || texture->download_count > WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD) + { + TRACE("Not evicting system memory for texture %p.\n", texture); + return; + } + + TRACE("Evicting system memory for texture %p.\n", texture); + + sub_count = texture->level_count * texture->layer_count; + for (i = 0; i < sub_count; ++i) + { + sub_resource = &texture->sub_resources[i]; + if (sub_resource->locations == WINED3D_LOCATION_SYSMEM) + ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n", + i, texture); + sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM; + } + wined3d_resource_free_sysmem(&texture->resource); +} + +void wined3d_texture_validate_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, DWORD location) +{ + struct wined3d_texture_sub_resource *sub_resource; + DWORD previous_locations; + + TRACE("texture %p, sub_resource_idx %u, location %s.\n", + texture, sub_resource_idx, wined3d_debug_location(location)); + + sub_resource = &texture->sub_resources[sub_resource_idx]; + previous_locations = sub_resource->locations; + sub_resource->locations |= location; + if (previous_locations == WINED3D_LOCATION_SYSMEM && location != WINED3D_LOCATION_SYSMEM + && !--texture->sysmem_count) + wined3d_texture_evict_sysmem(texture); + + TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations)); +} + +static void wined3d_texture_set_dirty(struct wined3d_texture *texture) +{ + texture->flags &= ~(WINED3D_TEXTURE_RGB_VALID | WINED3D_TEXTURE_SRGB_VALID); +} + +void wined3d_texture_invalidate_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, DWORD location) +{ + struct wined3d_texture_sub_resource *sub_resource; + DWORD previous_locations; + + TRACE("texture %p, sub_resource_idx %u, location %s.\n", + texture, sub_resource_idx, wined3d_debug_location(location)); + + if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + wined3d_texture_set_dirty(texture); + + sub_resource = &texture->sub_resources[sub_resource_idx]; + previous_locations = sub_resource->locations; + sub_resource->locations &= ~location; + if (previous_locations != WINED3D_LOCATION_SYSMEM && sub_resource->locations == WINED3D_LOCATION_SYSMEM) + ++texture->sysmem_count; + + TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations)); + + if (!sub_resource->locations) + ERR("Sub-resource %u of texture %p does not have any up to date location.\n", + sub_resource_idx, texture); +} + +static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + unsigned int size = texture->sub_resources[sub_resource_idx].size; + struct wined3d_device *device = texture->resource.device; + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location); + wined3d_texture_get_memory(texture, sub_resource_idx, &src, + texture->sub_resources[sub_resource_idx].locations); + + if (dst.buffer_object) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); + GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("PBO upload"); + context_release(context); + return TRUE; + } + + if (src.buffer_object) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); + GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("PBO download"); + context_release(context); + return TRUE; + } + + memcpy(dst.addr, src.addr, size); + return TRUE; +} + +/* Context activation is done by the caller. Context may be NULL in + * WINED3D_NO3D mode. */ +BOOL wined3d_texture_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + static const DWORD sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY + | WINED3D_LOCATION_BUFFER; + DWORD current = texture->sub_resources[sub_resource_idx].locations; + BOOL ret; + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + TRACE("Current resource location %s.\n", wined3d_debug_location(current)); + + if (current & location) + { + TRACE("Location %s is already up to date.\n", wined3d_debug_location(location)); + return TRUE; + } + + if (WARN_ON(d3d)) + { + DWORD required_access = wined3d_resource_access_from_location(location); + if ((texture->resource.access_flags & required_access) != required_access) + WARN("Operation requires %#x access, but texture only has %#x.\n", + required_access, texture->resource.access_flags); + } + + if (current & WINED3D_LOCATION_DISCARDED) + { + TRACE("Sub-resource previously discarded, nothing to do.\n"); + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + wined3d_texture_validate_location(texture, sub_resource_idx, location); + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); + return TRUE; + } + + if (!current) + { + ERR("Sub-resource %u of texture %p does not have any up to date location.\n", + sub_resource_idx, texture); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); + return wined3d_texture_load_location(texture, sub_resource_idx, context, location); + } + + if ((location & sysmem_locations) && (current & sysmem_locations)) + ret = wined3d_texture_copy_sysmem_location(texture, sub_resource_idx, context, location); + else + ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location); + + if (ret) + wined3d_texture_validate_location(texture, sub_resource_idx, location); + + return ret; +} + +void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_bo_address *data, DWORD locations) +{ + struct wined3d_texture_sub_resource *sub_resource; + + TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n", + texture, sub_resource_idx, data, wined3d_debug_location(locations)); + + sub_resource = &texture->sub_resources[sub_resource_idx]; + if (locations & WINED3D_LOCATION_BUFFER) + { + data->addr = NULL; +#if !defined(STAGING_CSMT) + data->buffer_object = sub_resource->buffer_object; +#else /* STAGING_CSMT */ + data->buffer_object = sub_resource->buffer->name; +#endif /* STAGING_CSMT */ + return; + } + if (locations & WINED3D_LOCATION_USER_MEMORY) + { + data->addr = texture->user_memory; + data->buffer_object = 0; + return; + } + if (locations & WINED3D_LOCATION_SYSMEM) + { + data->addr = texture->resource.heap_memory; + data->addr += sub_resource->offset; + data->buffer_object = 0; + return; + } + + ERR("Unexpected locations %s.\n", wined3d_debug_location(locations)); + data->addr = NULL; + data->buffer_object = 0; +} + static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops, UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { - const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format); + unsigned int i, j, size, offset = 0; + const struct wined3d_format *format; HRESULT hr; TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, " @@ -41,9 +335,32 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops); + if (!desc->width || !desc->height || !desc->depth) + return WINED3DERR_INVALIDCALL; + + format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage); + + for (i = 0; i < layer_count; ++i) + { + for (j = 0; j < level_count; ++j) + { + unsigned int idx = i * level_count + j; + + size = wined3d_format_calculate_size(format, device->surface_alignment, + max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j)); + texture->sub_resources[idx].offset = offset; + texture->sub_resources[idx].size = size; + offset += size; + } + offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1); + } + + if (!offset) + return WINED3DERR_INVALIDCALL; + if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool, - desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops))) + desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops))) { static unsigned int once; @@ -58,6 +375,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc return hr; } wined3d_resource_update_draw_binding(&texture->resource); + if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE) + texture->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU; texture->texture_ops = texture_ops; @@ -65,35 +384,194 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc texture->level_count = level_count; texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE; texture->lod = 0; - texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; - if (flags & WINED3D_TEXTURE_CREATE_PIN_SYSMEM) - texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; + texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; + if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) + texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; + if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) + texture->flags |= WINED3D_TEXTURE_GET_DC; + if (flags & WINED3D_TEXTURE_CREATE_DISCARD) + texture->flags |= WINED3D_TEXTURE_DISCARD; return WINED3D_OK; } -/* A GL context is provided by the caller */ -static void gltexture_delete(const struct wined3d_gl_info *gl_info, struct gl_texture *tex) +/* Context activation is done by the caller. */ +static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, +#if !defined(STAGING_CSMT) + unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) { + GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object; + + GL_EXTCALL(glDeleteBuffers(1, buffer_object)); + checkGLcall("glDeleteBuffers"); + + TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n", + *buffer_object, texture, sub_resource_idx); + + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); + *buffer_object = 0; +#else /* STAGING_CSMT */ + unsigned int sub_resource_idx, struct wined3d_context *context) +{ + struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer; + GLuint name = buffer->name; + + wined3d_device_release_bo(texture->resource.device, buffer, context); + texture->sub_resources[sub_resource_idx].buffer = NULL; + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); + + TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n", + name, texture, sub_resource_idx); +#endif /* STAGING_CSMT */ +} + +static void wined3d_texture_update_map_binding(struct wined3d_texture *texture) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + const struct wined3d_device *device = texture->resource.device; + DWORD map_binding = texture->update_map_binding; + struct wined3d_context *context = NULL; + unsigned int i; + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + for (i = 0; i < sub_count; ++i) + { + if (texture->sub_resources[i].locations == texture->resource.map_binding + && !wined3d_texture_load_location(texture, i, context, map_binding)) + ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding)); + if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER) +#if !defined(STAGING_CSMT) + wined3d_texture_remove_buffer_object(texture, i, context->gl_info); +#else /* STAGING_CSMT */ + wined3d_texture_remove_buffer_object(texture, i, context); +#endif /* STAGING_CSMT */ + } + + if (context) + context_release(context); + + texture->resource.map_binding = map_binding; + texture->update_map_binding = 0; +} + +void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) +{ + texture->update_map_binding = map_binding; + if (!texture->resource.map_count) + wined3d_texture_update_map_binding(texture); +} + +/* A GL context is provided by the caller */ +static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info, + struct gl_texture *tex) +{ + context_gl_resource_released(device, tex->name, FALSE); gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex->name); tex->name = 0; } +/* Context activation is done by the caller. */ +/* The caller is responsible for binding the correct texture. */ +static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *texture, + GLenum gl_internal_format, const struct wined3d_format *format, + const struct wined3d_gl_info *gl_info) +{ + unsigned int i, sub_call_count; + + sub_call_count = texture->level_count; + if (texture->target != GL_TEXTURE_2D_ARRAY) + sub_call_count *= texture->layer_count; + + for (i = 0; i < sub_call_count; ++i) + { + struct wined3d_surface *surface = texture->sub_resources[i].u.surface; + GLsizei width, height; + + width = wined3d_texture_get_level_pow2_width(texture, surface->texture_level); + height = wined3d_texture_get_level_pow2_height(texture, surface->texture_level); + if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE) + { + height *= format->height_scale.numerator; + height /= format->height_scale.denominator; + } + + TRACE("surface %p, target %#x, level %u, width %u, height %u.\n", + surface, surface->texture_target, surface->texture_level, width, height); + + if (texture->target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexImage3D(surface->texture_target, surface->texture_level, + gl_internal_format, width, height, texture->layer_count, 0, + format->glFormat, format->glType, NULL)); + checkGLcall("glTexImage3D"); + } + else + { + gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, + gl_internal_format, width, height, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage2D"); + } + } +} + +/* Context activation is done by the caller. */ +/* The caller is responsible for binding the correct texture. */ +static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture *texture, + GLenum gl_internal_format, const struct wined3d_gl_info *gl_info) +{ + GLsizei width = wined3d_texture_get_level_pow2_width(texture, 0); + GLsizei height = wined3d_texture_get_level_pow2_height(texture, 0); + + if (texture->target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count, gl_internal_format, + width, height, texture->layer_count)); + checkGLcall("glTexStorage3D"); + } + else + { + GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, gl_internal_format, + width, height)); + checkGLcall("glTexStorage2D"); + } +} + static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) { struct wined3d_device *device = texture->resource.device; + const struct wined3d_gl_info *gl_info = NULL; struct wined3d_context *context = NULL; - if (texture->texture_rgb.name || texture->texture_srgb.name) + if (texture->texture_rgb.name || texture->texture_srgb.name + || texture->rb_multisample || texture->rb_resolved) { - context = context_acquire(device, NULL); + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; } if (texture->texture_rgb.name) - gltexture_delete(context->gl_info, &texture->texture_rgb); + gltexture_delete(device, context->gl_info, &texture->texture_rgb); if (texture->texture_srgb.name) - gltexture_delete(context->gl_info, &texture->texture_srgb); + gltexture_delete(device, context->gl_info, &texture->texture_srgb); + + if (texture->rb_multisample) + { + TRACE("Deleting multisample renderbuffer %u.\n", texture->rb_multisample); + context_gl_resource_released(device, texture->rb_multisample, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_multisample); + texture->rb_multisample = 0; + } + + if (texture->rb_resolved) + { + TRACE("Deleting resolved renderbuffer %u.\n", texture->rb_resolved); + context_gl_resource_released(device, texture->rb_resolved, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_resolved); + texture->rb_resolved = 0; + } if (context) context_release(context); @@ -102,42 +580,75 @@ static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) resource_unload(&texture->resource); } -#if defined(STAGING_CSMT) -void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) +static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) { - wined3d_texture_unload_gl_texture(texture); - HeapFree(GetProcessHeap(), 0, texture); + unsigned int sub_count = texture->level_count * texture->layer_count; + struct wined3d_texture_sub_resource *sub_resource; + unsigned int i; + + for (i = 0; i < sub_count; ++i) + { + sub_resource = &texture->sub_resources[i]; + if (sub_resource->parent) + { + TRACE("sub-resource %u.\n", i); + sub_resource->parent_ops->wined3d_object_destroyed(sub_resource->parent); + sub_resource->parent = NULL; + } + } } static void wined3d_texture_cleanup(struct wined3d_texture *texture) { - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; + unsigned int sub_count = texture->level_count * texture->layer_count; struct wined3d_device *device = texture->resource.device; + struct wined3d_context *context = NULL; +#if !defined(STAGING_CSMT) + const struct wined3d_gl_info *gl_info; + GLuint buffer_object; #else /* STAGING_CSMT */ -static void wined3d_texture_cleanup(struct wined3d_texture *texture) -{ - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; + struct wined3d_gl_bo *buffer; #endif /* STAGING_CSMT */ + unsigned int i; TRACE("texture %p.\n", texture); for (i = 0; i < sub_count; ++i) { - struct wined3d_resource *sub_resource = texture->sub_resources[i].resource; +#if !defined(STAGING_CSMT) + if (!(buffer_object = texture->sub_resources[i].buffer_object)) + continue; - if (sub_resource) - texture->texture_ops->texture_sub_resource_cleanup(sub_resource); - } - -#if defined(STAGING_CSMT) - resource_cleanup(&texture->resource); - wined3d_cs_emit_texture_cleanup(device->cs, texture); + TRACE("Deleting buffer object %u.\n", buffer_object); #else /* STAGING_CSMT */ - wined3d_texture_unload_gl_texture(texture); - resource_cleanup(&texture->resource); + if (!(buffer = texture->sub_resources[i].buffer)) + continue; + + TRACE("Deleting buffer object %u.\n", buffer->name); #endif /* STAGING_CSMT */ + + /* We may not be able to get a context in wined3d_texture_cleanup() in + * general, but if a buffer object was previously created we can. */ + if (!context) +#if !defined(STAGING_CSMT) + { + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + } + + GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); +#else /* STAGING_CSMT */ + context = context_acquire(device, NULL, 0); + + wined3d_device_release_bo(device, buffer, context); + texture->sub_resources[i].buffer = NULL; +#endif /* STAGING_CSMT */ + } + if (context) + context_release(context); + + texture->texture_ops->texture_cleanup_sub_resources(texture); + wined3d_texture_unload_gl_texture(texture); } void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) @@ -146,22 +657,19 @@ void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined wined3d_resource_update_draw_binding(&texture->resource); } -void wined3d_texture_set_dirty(struct wined3d_texture *texture) -{ - texture->flags &= ~(WINED3D_TEXTURE_RGB_VALID | WINED3D_TEXTURE_SRGB_VALID); -} - /* Context activation is done by the caller. */ void wined3d_texture_bind(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_format *format = texture->resource.format; + const struct color_fixup_desc fixup = format->color_fixup; struct gl_texture *gl_tex; GLenum target; TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); - if (!needs_separate_srgb_gl_texture(context)) + if (!needs_separate_srgb_gl_texture(context, texture)) srgb = FALSE; /* sRGB mode cache for preload() calls outside drawprim. */ @@ -267,14 +775,37 @@ void wined3d_texture_bind(struct wined3d_texture *texture, gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)"); } + + if (!is_identity_fixup(fixup) && can_use_texture_swizzle(gl_info, format)) + { + static const GLenum swizzle_source[] = + { + GL_ZERO, /* CHANNEL_SOURCE_ZERO */ + GL_ONE, /* CHANNEL_SOURCE_ONE */ + GL_RED, /* CHANNEL_SOURCE_X */ + GL_GREEN, /* CHANNEL_SOURCE_Y */ + GL_BLUE, /* CHANNEL_SOURCE_Z */ + GL_ALPHA, /* CHANNEL_SOURCE_W */ + }; + struct + { + GLint x, y, z, w; + } + swizzle; + + swizzle.x = swizzle_source[fixup.x_source]; + swizzle.y = swizzle_source[fixup.y_source]; + swizzle.z = swizzle_source[fixup.z_source]; + swizzle.w = swizzle_source[fixup.w_source]; + gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, &swizzle.x); + checkGLcall("glTexParameteriv(GL_TEXTURE_SWIZZLE_RGBA)"); + } } /* Context activation is done by the caller. */ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { - DWORD active_sampler; - /* We don't need a specific texture unit, but after binding the texture * the current unit is dirty. Read the unit back instead of switching to * 0, this avoids messing around with the state manager's GL states. The @@ -284,12 +815,16 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, * called from sampler() in state.c. This means we can't touch anything * other than whatever happens to be the currently active texture, or we * would risk marking already applied sampler states dirty again. */ - active_sampler = context->rev_tex_unit_map[context->active_texture]; - if (active_sampler != WINED3D_UNMAPPED_STAGE) - context_invalidate_state(context, STATE_SAMPLER(active_sampler)); + if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map)) + { + DWORD active_sampler = context->rev_tex_unit_map[context->active_texture]; + if (active_sampler != WINED3D_UNMAPPED_STAGE) + context_invalidate_state(context, STATE_SAMPLER(active_sampler)); + } /* FIXME: Ideally we'd only do this when touching a binding that's used by * a shader. */ - context_invalidate_state(context, STATE_SHADER_RESOURCE_BINDING); + context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); wined3d_texture_bind(texture, context, srgb); } @@ -409,6 +944,20 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture) return refcount; } +static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture) +{ + wined3d_texture_sub_resources_destroyed(texture); + resource_cleanup(&texture->resource); + wined3d_resource_wait_idle(&texture->resource); + wined3d_texture_cleanup(texture); +} + +static void wined3d_texture_destroy_object(void *object) +{ + wined3d_texture_cleanup(object); + HeapFree(GetProcessHeap(), 0, object); +} + ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) { ULONG refcount; @@ -423,16 +972,16 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) if (!refcount) { -#if defined(STAGING_CSMT) - void *parent = texture->resource.parent; - const struct wined3d_parent_ops *parent_ops = texture->resource.parent_ops; - wined3d_texture_cleanup(texture); - parent_ops->wined3d_object_destroyed(parent); -#else /* STAGING_CSMT */ - wined3d_texture_cleanup(texture); + /* Wait for the texture to become idle if it's using user memory, + * since the application is allowed to free that memory once the + * texture is destroyed. Note that this implies that + * wined3d_texture_destroy_object() can't access that memory either. */ + if (texture->user_memory) + wined3d_resource_wait_idle(&texture->resource); + wined3d_texture_sub_resources_destroyed(texture); texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ + resource_cleanup(&texture->resource); + wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); } return refcount; @@ -462,7 +1011,7 @@ void wined3d_texture_load(struct wined3d_texture *texture, TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); - if (!needs_separate_srgb_gl_texture(context)) + if (!needs_separate_srgb_gl_texture(context, texture)) srgb = FALSE; if (srgb) @@ -481,8 +1030,12 @@ void wined3d_texture_load(struct wined3d_texture *texture, TRACE("Reloading because of color key value change.\n"); for (i = 0; i < sub_count; i++) - texture->texture_ops->texture_sub_resource_add_dirty_region(texture->sub_resources[i].resource, NULL); - wined3d_texture_set_dirty(texture); + { + if (!wined3d_texture_load_location(texture, i, context, texture->resource.map_binding)) + ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding)); + else + wined3d_texture_invalidate_location(texture, i, ~texture->resource.map_binding); + } texture->async.gl_color_key = texture->async.src_blt_color_key; } @@ -496,24 +1049,13 @@ void wined3d_texture_load(struct wined3d_texture *texture, /* Reload the surfaces if the texture is marked dirty. */ for (i = 0; i < sub_count; ++i) { - texture->texture_ops->texture_sub_resource_load(texture->sub_resources[i].resource, context, srgb); + if (!wined3d_texture_load_location(texture, i, context, + srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB)) + ERR("Failed to load location (srgb %#x).\n", srgb); } texture->flags |= flag; } -void CDECL wined3d_texture_preload(struct wined3d_texture *texture) -{ -#if defined(STAGING_CSMT) - const struct wined3d_device *device = texture->resource.device; - wined3d_cs_emit_texture_preload(device->cs, texture); -#else /* STAGING_CSMT */ - struct wined3d_context *context; - context = context_acquire(texture->resource.device, NULL); - wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); - context_release(context); -#endif /* STAGING_CSMT */ -} - void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) { TRACE("texture %p.\n", texture); @@ -521,47 +1063,52 @@ void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) return texture->resource.parent; } +HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, + unsigned int level, const struct wined3d_box *box) +{ + const struct wined3d_format *format = texture->resource.format; + unsigned int width_mask, height_mask, width, height, depth; + + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + depth = wined3d_texture_get_level_depth(texture, level); + + if (box->left >= box->right || box->right > width + || box->top >= box->bottom || box->bottom > height + || box->front >= box->back || box->back > depth) + { + WARN("Box %s is invalid.\n", debug_box(box)); + return WINEDDERR_INVALIDRECT; + } + + if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + { + /* This assumes power of two block sizes, but NPOT block sizes would + * be silly anyway. + * + * This also assumes that the format's block depth is 1. */ + width_mask = format->block_width - 1; + height_mask = format->block_height - 1; + + if ((box->left & width_mask) || (box->top & height_mask) + || (box->right & width_mask && box->right != width) + || (box->bottom & height_mask && box->bottom != height)) + { + WARN("Box %s is misaligned for %ux%u blocks.\n", + debug_box(box), format->block_width, format->block_height); + return WINED3DERR_INVALIDCALL; + } + } + + return WINED3D_OK; +} + void CDECL wined3d_texture_get_pitch(const struct wined3d_texture *texture, unsigned int level, unsigned int *row_pitch, unsigned int *slice_pitch) { const struct wined3d_resource *resource = &texture->resource; -#if defined(STAGING_CSMT) - const struct wined3d_format *format = resource->format; - unsigned int alignment = resource->device->surface_alignment; - unsigned int width = max(1, texture->resource.width >> level); - unsigned int height = max(1, texture->resource.height >> level); - - if (texture->row_pitch) - { - *row_pitch = texture->row_pitch; - *slice_pitch = *row_pitch * height; - return; - } - - if (resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) - { - unsigned int row_block_count = (width + format->block_width - 1) / format->block_width; - unsigned int slice_block_count = (height + format->block_height - 1) / format->block_height; - *row_pitch = row_block_count * format->block_byte_count; - *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); - *slice_pitch = *row_pitch * slice_block_count; - } - else - { - *row_pitch = format->byte_count * width; /* Bytes / row */ - *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); - *slice_pitch = *row_pitch * height; - } - - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) - { - /* The D3D format requirements make sure that the resulting format is an integer again */ - *slice_pitch *= format->height_scale.numerator; - *slice_pitch /= format->height_scale.denominator; - } -#else /* STAGING_CSMT */ - unsigned int width = max(1, texture->resource.width >> level); - unsigned int height = max(1, texture->resource.height >> level); + unsigned int width = wined3d_texture_get_level_width(texture, level); + unsigned int height = wined3d_texture_get_level_height(texture, level); if (texture->row_pitch) { @@ -572,7 +1119,6 @@ void CDECL wined3d_texture_get_pitch(const struct wined3d_texture *texture, wined3d_format_calculate_pitch(resource->format, resource->device->surface_alignment, width, height, row_pitch, slice_pitch); -#endif /* STAGING_CSMT */ } DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) @@ -594,21 +1140,16 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) if (texture->lod != lod) { -#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - { - struct wined3d_device *device = texture->resource.device; - FIXME("Waiting for cs.\n"); - device->cs->ops->finish(device->cs); - } + struct wined3d_device *device = texture->resource.device; -#endif /* STAGING_CSMT */ + wined3d_resource_wait_idle(&texture->resource); texture->lod = lod; texture->texture_rgb.base_level = ~0u; texture->texture_srgb.base_level = ~0u; if (texture->resource.bind_count) - device_invalidate_state(texture->resource.device, STATE_SAMPLER(texture->sampler)); + wined3d_cs_emit_set_sampler_state(device->cs, texture->sampler, WINED3D_SAMP_MAX_MIP_LEVEL, + device->state.sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); } return old; @@ -671,19 +1212,122 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, return WINED3D_OK; } +static void texture2d_create_dc(void *object) +{ + struct wined3d_surface *surface = object; + struct wined3d_context *context = NULL; + const struct wined3d_format *format; + unsigned int row_pitch, slice_pitch; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + D3DKMT_CREATEDCFROMMEMORY desc; + unsigned int sub_resource_idx; + struct wined3d_device *device; + NTSTATUS status; + + TRACE("surface %p.\n", surface); + + texture = surface->container; + sub_resource_idx = surface_get_sub_resource_idx(surface); + device = texture->resource.device; + + format = texture->resource.format; + if (!format->ddi_format) + { + WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id)); + return; + } + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); + wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch); + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + desc.pMemory = context_map_bo_address(context, &data, + texture->sub_resources[sub_resource_idx].size, GL_PIXEL_UNPACK_BUFFER, 0); + + if (context) + context_release(context); + + desc.Format = format->ddi_format; + desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level); + desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level); + desc.Pitch = row_pitch; + desc.hDeviceDc = CreateCompatibleDC(NULL); + desc.pColorTable = NULL; + + status = D3DKMTCreateDCFromMemory(&desc); + DeleteDC(desc.hDeviceDc); + if (status) + { + WARN("Failed to create DC, status %#x.\n", status); + return; + } + + surface->dc = desc.hDc; + surface->bitmap = desc.hBitmap; + + TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface); +} + +static void texture2d_destroy_dc(void *object) +{ + struct wined3d_surface *surface = object; + D3DKMT_DESTROYDCFROMMEMORY destroy_desc; + struct wined3d_context *context = NULL; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + unsigned int sub_resource_idx; + struct wined3d_device *device; + NTSTATUS status; + + texture = surface->container; + sub_resource_idx = surface_get_sub_resource_idx(surface); + device = texture->resource.device; + + if (!surface->dc) + { + ERR("Surface %p has no DC.\n", surface); + return; + } + + TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap); + + destroy_desc.hDc = surface->dc; + destroy_desc.hBitmap = surface->bitmap; + if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) + ERR("Failed to destroy dc, status %#x.\n", status); + surface->dc = NULL; + surface->bitmap = NULL; + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + if (context) + context_release(context); +} + HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality, void *mem, UINT pitch) { struct wined3d_device *device = texture->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); + const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage); UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); + struct wined3d_texture_sub_resource *sub_resource; struct wined3d_surface *surface; + DWORD valid_location = 0; + BOOL create_dib = FALSE; TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, " "mem %p, pitch %u.\n", - texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_type, mem, pitch); + texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch); if (!resource_size) return WINED3DERR_INVALIDCALL; @@ -700,6 +1344,18 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT return WINED3DERR_INVALIDCALL; } + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D) + { + FIXME("Not yet supported for 1D textures.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (texture->resource.map_count) + { + WARN("Texture is mapped.\n"); + return WINED3DERR_INVALIDCALL; + } + /* We have no way of supporting a pitch that is not a multiple of the pixel * byte width short of uploading the texture row-by-row. * Fortunately that's not an issue since D3D9Ex doesn't allow a custom pitch @@ -713,40 +1369,21 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT return WINED3DERR_INVALIDCALL; } - surface = surface_from_resource(texture->sub_resources[0].resource); - if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE)) - { - WARN("Surface is mapped or the DC is in use.\n"); - return WINED3DERR_INVALIDCALL; - } - if (device->d3d_initialized) -#if defined(STAGING_CSMT) + wined3d_cs_emit_unload_resource(device->cs, &texture->resource); + wined3d_resource_wait_idle(&texture->resource); + + sub_resource = &texture->sub_resources[0]; + surface = sub_resource->u.surface; + if (surface->dc) { - wined3d_cs_emit_evict_resource(device->cs, &surface->resource); - device->cs->ops->finish(device->cs); + wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + create_dib = TRUE; } -#else /* STAGING_CSMT */ - texture->resource.resource_ops->resource_unload(&texture->resource); -#endif /* STAGING_CSMT */ - texture->resource.format = format; - texture->resource.multisample_type = multisample_type; - texture->resource.multisample_quality = multisample_quality; - texture->resource.width = width; - texture->resource.height = height; + wined3d_resource_free_sysmem(&texture->resource); -#if defined(STAGING_CSMT) - texture->row_pitch = pitch; - - texture->flags &= ~WINED3D_TEXTURE_COND_NP2_EMULATED; - if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] - && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; - - return wined3d_surface_update_desc(surface, gl_info, mem, pitch); -#else /* STAGING_CSMT */ - texture->user_memory = mem; if ((texture->row_pitch = pitch)) texture->slice_pitch = height * pitch; else @@ -754,13 +1391,110 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT wined3d_format_calculate_pitch(format, 1, width, height, &texture->row_pitch, &texture->slice_pitch); - texture->flags &= ~WINED3D_TEXTURE_COND_NP2_EMULATED; - if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] - && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; + texture->resource.format = format; + texture->resource.multisample_type = multisample_type; + texture->resource.multisample_quality = multisample_quality; + texture->resource.width = width; + texture->resource.height = height; + texture->resource.size = texture->slice_pitch; + sub_resource->size = texture->slice_pitch; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; - return wined3d_surface_update_desc(surface, gl_info); + if ((!is_power_of_two(width) || !is_power_of_two(height)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] + && !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) + { + texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; + texture->pow2_width = texture->pow2_height = 1; + while (texture->pow2_width < width) + texture->pow2_width <<= 1; + while (texture->pow2_height < height) + texture->pow2_height <<= 1; + } + else + { + texture->flags &= ~WINED3D_TEXTURE_COND_NP2_EMULATED; + texture->pow2_width = width; + texture->pow2_height = height; + } + + if ((texture->user_memory = mem)) + { + texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; + valid_location = WINED3D_LOCATION_USER_MEMORY; + } + else + { + wined3d_texture_prepare_location(texture, 0, NULL, WINED3D_LOCATION_SYSMEM); + valid_location = WINED3D_LOCATION_SYSMEM; + } + + /* The format might be changed to a format that needs conversion. + * If the surface didn't use PBOs previously but could now, don't + * change it - whatever made us not use PBOs might come back, e.g. + * color keys. */ + if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info)) + texture->resource.map_binding = WINED3D_LOCATION_SYSMEM; + + wined3d_texture_validate_location(texture, 0, valid_location); + wined3d_texture_invalidate_location(texture, 0, ~valid_location); + + if (create_dib) + { + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + } + + return WINED3D_OK; +} + +/* Context activation is done by the caller. */ +static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, +#if !defined(STAGING_CSMT) + unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) +#else /* STAGING_CSMT */ + unsigned int sub_resource_idx, struct wined3d_context *context) #endif /* STAGING_CSMT */ +{ + struct wined3d_texture_sub_resource *sub_resource; + + sub_resource = &texture->sub_resources[sub_resource_idx]; +#if !defined(STAGING_CSMT) + if (sub_resource->buffer_object) + return; + + GL_EXTCALL(glGenBuffers(1, &sub_resource->buffer_object)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sub_resource->buffer_object)); + GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sub_resource->size, NULL, GL_STREAM_DRAW)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("Create buffer object"); + + TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", + sub_resource->buffer_object, texture, sub_resource_idx); +#else /* STAGING_CSMT */ + if (sub_resource->buffer) + return; + + sub_resource->buffer = wined3d_device_get_bo(texture->resource.device, + sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); + + TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", + sub_resource->buffer->name, texture, sub_resource_idx); +#endif /* STAGING_CSMT */ +} + +static void wined3d_texture_force_reload(struct wined3d_texture *texture) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + unsigned int i; + + texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED + | WINED3D_TEXTURE_CONVERTED); + texture->async.flags &= ~WINED3D_TEXTURE_ASYNC_COLOR_KEY; + for (i = 0; i < sub_count; ++i) + { + wined3d_texture_invalidate_location(texture, i, + WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); + } } void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) @@ -785,18 +1519,123 @@ void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct win texture->flags |= alloc_flag; } -void wined3d_texture_force_reload(struct wined3d_texture *texture) +static void wined3d_texture_prepare_rb(struct wined3d_texture *texture, + const struct wined3d_gl_info *gl_info, BOOL multisample) { - unsigned int sub_count = texture->level_count * texture->layer_count; - unsigned int i; + const struct wined3d_format *format = texture->resource.format; - texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED - | WINED3D_TEXTURE_CONVERTED); - texture->async.flags &= ~WINED3D_TEXTURE_ASYNC_COLOR_KEY; - for (i = 0; i < sub_count; ++i) + if (multisample) { - texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[i].resource, - WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB); + DWORD samples; + + if (texture->rb_multisample) + return; + + /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA) + * feature through type == MULTISAMPLE_XX and quality != 0. This could + * be mapped to GL_NV_framebuffer_multisample_coverage. + * + * AMD have a similar feature called Enhanced Quality Anti-Aliasing + * (EQAA), but it does not have an equivalent OpenGL extension. */ + + /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality + * levels as the count of advertised multisample types for the texture + * format. */ + if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) + { + unsigned int i, count = 0; + + for (i = 0; i < sizeof(format->multisample_types) * 8; ++i) + { + if (format->multisample_types & 1u << i) + { + if (texture->resource.multisample_quality == count++) + break; + } + } + samples = i + 1; + } + else + { + samples = texture->resource.multisample_type; + } + + gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample); + gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, + format->glInternal, texture->resource.width, texture->resource.height); + checkGLcall("glRenderbufferStorageMultisample()"); + TRACE("Created multisample rb %u.\n", texture->rb_multisample); + } + else + { + if (texture->rb_resolved) + return; + + gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_resolved); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_resolved); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal, + texture->resource.width, texture->resource.height); + checkGLcall("glRenderbufferStorage()"); + TRACE("Created resolved rb %u.\n", texture->rb_resolved); + } +} + +/* Context activation is done by the caller. Context may be NULL in + * WINED3D_NO3D mode. */ +BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + if (texture->resource.heap_memory) + return TRUE; + + if (!wined3d_resource_allocate_sysmem(&texture->resource)) + { + ERR("Failed to allocate system memory.\n"); + return FALSE; + } + return TRUE; + + case WINED3D_LOCATION_USER_MEMORY: + if (!texture->user_memory) + ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); + return TRUE; + + case WINED3D_LOCATION_BUFFER: +#if !defined(STAGING_CSMT) + wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info); +#else /* STAGING_CSMT */ + wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context); +#endif /* STAGING_CSMT */ + return TRUE; + + case WINED3D_LOCATION_TEXTURE_RGB: + wined3d_texture_prepare_texture(texture, context, FALSE); + return TRUE; + + case WINED3D_LOCATION_TEXTURE_SRGB: + wined3d_texture_prepare_texture(texture, context, TRUE); + return TRUE; + + case WINED3D_LOCATION_DRAWABLE: + if (!texture->swapchain && wined3d_settings.offscreen_rendering_mode != ORM_BACKBUFFER) + ERR("Texture %p does not have a drawable.\n", texture); + return TRUE; + + case WINED3D_LOCATION_RB_MULTISAMPLE: + wined3d_texture_prepare_rb(texture, context->gl_info, TRUE); + return TRUE; + + case WINED3D_LOCATION_RB_RESOLVED: + wined3d_texture_prepare_rb(texture, context->gl_info, FALSE); + return TRUE; + + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; } } @@ -806,8 +1645,8 @@ void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture) FIXME("texture %p stub!\n", texture); } -struct wined3d_resource * CDECL wined3d_texture_get_sub_resource(const struct wined3d_texture *texture, - UINT sub_resource_idx) +static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture, + unsigned int sub_resource_idx) { UINT sub_count = texture->level_count * texture->layer_count; @@ -819,148 +1658,452 @@ struct wined3d_resource * CDECL wined3d_texture_get_sub_resource(const struct wi return NULL; } - return texture->sub_resources[sub_resource_idx].resource; + return &texture->sub_resources[sub_resource_idx]; } HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region) { - struct wined3d_resource *sub_resource; - TRACE("texture %p, layer %u, dirty_region %s.\n", texture, layer, debug_box(dirty_region)); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture, layer * texture->level_count))) + if (layer >= texture->layer_count) { - WARN("Failed to get sub-resource.\n"); + WARN("Invalid layer %u specified.\n", layer); return WINED3DERR_INVALIDCALL; } - texture->texture_ops->texture_sub_resource_add_dirty_region(sub_resource, dirty_region); + if (dirty_region) + WARN("Ignoring dirty_region %s.\n", debug_box(dirty_region)); + + wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer); return WINED3D_OK; } -static HRESULT wined3d_texture_upload_data(struct wined3d_texture *texture, - const struct wined3d_sub_resource_data *data) +void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) { - unsigned int sub_count = texture->level_count * texture->layer_count; - struct wined3d_context *context; - unsigned int i; + texture->texture_ops->texture_upload_data(texture, sub_resource_idx, + context, box, data, row_pitch, slice_pitch); +} - for (i = 0; i < sub_count; ++i) + +/* This call just uploads data, the caller is responsible for binding the + * correct texture. */ +/* Context activation is done by the caller. */ +static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data, + unsigned int row_pitch, unsigned int slice_pitch) +{ + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + const struct wined3d_format *format = texture->resource.format; + unsigned int level = sub_resource_idx % texture->level_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + const void *mem = data->addr; + void *converted_mem = NULL; + unsigned int width, x, update_w; + + TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", + texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch); + + width = wined3d_texture_get_level_width(texture, level); + + if (!box) { - if (!data[i].data) + x = 0; + update_w = width; + } + else + { + x = box->left; + update_w = box->right - box->left; + } + + if (format->convert) + { + unsigned int dst_row_pitch; + + if (data->buffer_object) + ERR("Loading a converted texture from a PBO.\n"); + if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + dst_row_pitch = update_w * format->conv_byte_count; + + converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch); + format->convert(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1); + mem = converted_mem; + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + if (surface->texture_target == GL_TEXTURE_1D_ARRAY) + { + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count); + + gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage2D"); + + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage1D(surface->texture_target, level, x, update_w, format->glFormat, format->glType, mem); + checkGLcall("glTexSubImage1D"); + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, converted_mem); +} + +/* Context activation is done by the caller. */ +static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_bo_address *data) +{ + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + const struct wined3d_format *format = texture->resource.format; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture_sub_resource *sub_resource; + BYTE *temporary_mem = NULL; + void *mem; + + sub_resource = &texture->sub_resources[sub_resource_idx]; + + if (format->convert) + { + FIXME("Attempting to download a converted 1d texture, format %s.\n", + debug_d3dformat(format->id)); + return; + } + + if (surface->texture_target == GL_TEXTURE_1D_ARRAY) + { + WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + + if (!(temporary_mem = wined3d_calloc(texture->layer_count, sub_resource->size))) { - WARN("Invalid sub-resource data specified for sub-resource %u.\n", i); - return E_INVALIDARG; + ERR("Out of memory.\n"); + return; + } + + mem = temporary_mem; + } + else if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + mem = data->addr; + } + else + mem = data->addr; + + gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, sub_resource_idx, + format->glFormat, format->glType, mem); + checkGLcall("glGetTexImage"); + + if (temporary_mem) + { + void *src_data = temporary_mem + surface->texture_layer * sub_resource->size; + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data)); + checkGLcall("glBufferSubData"); + } + else + { + memcpy(data->addr, src_data, sub_resource->size); } } - context = context_acquire(texture->resource.device, NULL); - - wined3d_texture_prepare_texture(texture, context, FALSE); - wined3d_texture_bind_and_dirtify(texture, context, FALSE); - - for (i = 0; i < sub_count; ++i) + if (data->buffer_object) { - struct wined3d_resource *sub_resource = texture->sub_resources[i].resource; - - texture->texture_ops->texture_sub_resource_upload_data(sub_resource, context, &data[i]); - texture->texture_ops->texture_sub_resource_validate_location(sub_resource, WINED3D_LOCATION_TEXTURE_RGB); - texture->texture_ops->texture_sub_resource_invalidate_location(sub_resource, ~WINED3D_LOCATION_TEXTURE_RGB); + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); } - context_release(context); - - return WINED3D_OK; + HeapFree(GetProcessHeap(), 0, temporary_mem); } -static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource, - struct wined3d_context *context, BOOL srgb) +/* Context activation is done by the caller. */ +static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, BOOL dest_is_srgb) { - surface_load(surface_from_resource(sub_resource), context, srgb); + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + unsigned int row_pitch, slice_pitch; + struct wined3d_bo_address data; + + WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n"); + data.buffer_object = 0; + if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size))) + return; + + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); + texture1d_download_data(texture, sub_resource_idx, context, &data); + wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, + wined3d_const_bo_address(&data), row_pitch, slice_pitch); + + HeapFree(GetProcessHeap(), 0, data.addr); } -static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource, - const struct wined3d_box *dirty_region) +/* Context activation is done by the caller. */ +static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) { - struct wined3d_surface *surface = surface_from_resource(sub_resource); - struct wined3d_context *context; + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + DWORD required_access = wined3d_resource_access_from_location(location); + unsigned int row_pitch, slice_pitch; -#if defined(STAGING_CSMT) - context = context_acquire(surface->resource.device, NULL); - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - context_release(context); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations)); + + if ((sub_resource->locations & location) == location) + { + TRACE("Location(s) already up to date.\n"); + return TRUE; + } + + if ((texture->resource.access_flags & required_access) != required_access) + { + ERR("Operation requires %#x access, but 1d texture only has %#x.\n", + required_access, texture->resource.access_flags); + return FALSE; + } + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + if (sub_resource->locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("1d texture previously discarded, nothing to do.\n"); + wined3d_texture_validate_location(texture, sub_resource_idx, location); + wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); + goto done; + } + + switch (location) + { + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) + { + struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; + data.addr += sub_resource->offset; + wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) + { +#if !defined(STAGING_CSMT) + struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; #else /* STAGING_CSMT */ - surface_prepare_map_memory(surface); - context = context_acquire(surface->resource.device, NULL); - surface_load_location(surface, context, surface->resource.map_binding); - context_release(context); - surface_invalidate_location(surface, ~surface->resource.map_binding); + struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; #endif /* STAGING_CSMT */ -} + wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + { + texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) + { + texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE); + } + else + { + FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; -static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource) -{ - struct wined3d_surface *surface = surface_from_resource(sub_resource); + case WINED3D_LOCATION_SYSMEM: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {0, texture->resource.heap_memory}; - wined3d_surface_destroy(surface); -} + data.addr += sub_resource->offset; + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); -static void texture2d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) -{ -#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(sub_resource, location); -} + texture1d_download_data(texture, sub_resource_idx, context, &data); + ++texture->download_count; + } + else + { + FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; -static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -{ - wined3d_resource_validate_location(sub_resource, location); + case WINED3D_LOCATION_BUFFER: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { +#if !defined(STAGING_CSMT) + struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; #else /* STAGING_CSMT */ - struct wined3d_surface *surface = surface_from_resource(sub_resource); - - surface_invalidate_location(surface, location); -} - -static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -{ - struct wined3d_surface *surface = surface_from_resource(sub_resource); - - surface_validate_location(surface, location); + struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; #endif /* STAGING_CSMT */ + + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture1d_download_data(texture, sub_resource_idx, context, &data); + } + else + { + FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + default: + FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + +done: + wined3d_texture_validate_location(texture, sub_resource_idx, location); + + return TRUE; } -static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource, - const struct wined3d_context *context, const struct wined3d_sub_resource_data *data) +static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { - struct wined3d_surface *surface = surface_from_resource(sub_resource); - static const POINT dst_point = {0, 0}; - struct wined3d_const_bo_address addr; + const struct wined3d_format *format = texture->resource.format; + unsigned int sub_count = texture->level_count * texture->layer_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int width; + GLenum internal; + + wined3d_texture_bind_and_dirtify(texture, context, srgb); + + if (srgb) + internal = format->glGammaInternal; + else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET + && wined3d_resource_is_offscreen(&texture->resource)) + internal = format->rtInternal; + else + internal = format->glInternal; + + if (wined3d_texture_use_immutable_storage(texture, gl_info)) + { + width = wined3d_texture_get_level_width(texture, 0); + + if (texture->target == GL_TEXTURE_1D_ARRAY) + { + GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count)); + checkGLcall("glTexStorage2D"); + } + else + { + GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width)); + checkGLcall("glTexStorage1D"); + } + } + else + { + unsigned int i; + + for (i = 0; i < sub_count; ++i) + { + struct wined3d_surface *surface = texture->sub_resources[i].u.surface; + width = wined3d_texture_get_level_width(texture, surface->texture_level); + + if (texture->target == GL_TEXTURE_1D_ARRAY) + { + gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, + internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage2D"); + } + else + { + gl_info->gl_ops.gl.p_glTexImage1D(surface->texture_target, surface->texture_level, + internal, width, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage1D"); + } + } + } +} + +static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture) +{ +} + +static const struct wined3d_texture_ops texture1d_ops = +{ + texture1d_upload_data, + texture1d_load_location, + texture1d_prepare_texture, + texture1d_cleanup_sub_resources, +}; + +static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + unsigned int texture_level; + POINT dst_point; RECT src_rect; src_rect.left = 0; src_rect.top = 0; - src_rect.right = surface->resource.width; - src_rect.bottom = surface->resource.height; + if (box) + { + dst_point.x = box->left; + dst_point.y = box->top; + src_rect.right = box->right - box->left; + src_rect.bottom = box->bottom - box->top; + } + else + { + dst_point.x = dst_point.y = 0; + texture_level = sub_resource_idx % texture->level_count; + src_rect.right = wined3d_texture_get_level_width(texture, texture_level); + src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level); + } - addr.buffer_object = 0; - addr.addr = data->data; + wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info, + texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data); +} - wined3d_surface_upload_data(surface, context->gl_info, surface->container->resource.format, - &src_rect, data->row_pitch, &dst_point, FALSE, &addr); +static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location); } /* Context activation is done by the caller. */ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { - UINT sub_count = texture->level_count * texture->layer_count; const struct wined3d_format *format = texture->resource.format; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_color_key_conversion *conversion; GLenum internal; - UINT i; TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id)); @@ -971,7 +2114,7 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) { texture->flags |= WINED3D_TEXTURE_CONVERTED; - format = wined3d_get_format(gl_info, conversion->dst_format); + format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage); TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id)); } @@ -990,170 +2133,613 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType); + if (wined3d_texture_use_immutable_storage(texture, gl_info)) + wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info); + else + wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info); +} + +static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + struct wined3d_device *device = texture->resource.device; + struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_renderbuffer_entry *entry, *entry2; + const struct wined3d_gl_info *gl_info = NULL; + struct wined3d_context *context = NULL; + struct wined3d_surface *overlay, *cur; + struct wined3d_surface *surface; + unsigned int i; + for (i = 0; i < sub_count; ++i) { - struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i].resource); - GLsizei height = surface->pow2Height; - GLsizei width = surface->pow2Width; + sub_resource = &texture->sub_resources[i]; + if (!(surface = sub_resource->u.surface)) + continue; - if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE) + TRACE("surface %p.\n", surface); + + if (!context && !list_empty(&surface->renderbuffers)) { - height *= format->height_scale.numerator; - height /= format->height_scale.denominator; + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; } - TRACE("surface %p, target %#x, level %d, width %d, height %d.\n", - surface, surface->texture_target, surface->texture_level, width, height); + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + TRACE("Deleting renderbuffer %u.\n", entry->id); + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + HeapFree(GetProcessHeap(), 0, entry); + } - gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, - internal, width, height, 0, format->glFormat, format->glType, NULL); - checkGLcall("glTexImage2D"); + if (surface->dc) + texture2d_destroy_dc(surface); + + if (surface->overlay_dest) + list_remove(&surface->overlay_entry); + + LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &surface->overlays, struct wined3d_surface, overlay_entry) + { + list_remove(&overlay->overlay_entry); + overlay->overlay_dest = NULL; + } } + if (context) + context_release(context); + HeapFree(GetProcessHeap(), 0, texture->sub_resources[0].u.surface); } static const struct wined3d_texture_ops texture2d_ops = { - texture2d_sub_resource_load, - texture2d_sub_resource_add_dirty_region, - texture2d_sub_resource_cleanup, - texture2d_sub_resource_invalidate_location, - texture2d_sub_resource_validate_location, - texture2d_sub_resource_upload_data, + texture2d_upload_data, + texture2d_load_location, texture2d_prepare_texture, + texture2d_cleanup_sub_resources, }; +struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource) +{ + return texture_from_resource(resource); +} + static ULONG texture_resource_incref(struct wined3d_resource *resource) { - return wined3d_texture_incref(wined3d_texture_from_resource(resource)); + return wined3d_texture_incref(texture_from_resource(resource)); } static ULONG texture_resource_decref(struct wined3d_resource *resource) { - return wined3d_texture_decref(wined3d_texture_from_resource(resource)); + return wined3d_texture_decref(texture_from_resource(resource)); +} + +static void texture_resource_preload(struct wined3d_resource *resource) +{ + struct wined3d_texture *texture = texture_from_resource(resource); + struct wined3d_context *context; + + context = context_acquire(resource->device, NULL, 0); + wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); + context_release(context); } static void wined3d_texture_unload(struct wined3d_resource *resource) { - struct wined3d_texture *texture = wined3d_texture_from_resource(resource); + struct wined3d_texture *texture = texture_from_resource(resource); UINT sub_count = texture->level_count * texture->layer_count; + struct wined3d_device *device = resource->device; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; UINT i; TRACE("texture %p.\n", texture); + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + for (i = 0; i < sub_count; ++i) { - struct wined3d_resource *sub_resource = texture->sub_resources[i].resource; + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i]; - sub_resource->resource_ops->resource_unload(sub_resource); + if (resource->pool != WINED3D_POOL_DEFAULT + && wined3d_texture_load_location(texture, i, context, resource->map_binding)) + { + wined3d_texture_invalidate_location(texture, i, ~resource->map_binding); + } + else + { + /* We should only get here on device reset/teardown for implicit + * resources. */ + if (resource->pool != WINED3D_POOL_DEFAULT || resource->type != WINED3D_RTYPE_TEXTURE_2D) + ERR("Discarding %s %p sub-resource %u in the %s pool.\n", debug_d3dresourcetype(resource->type), + resource, i, debug_d3dpool(resource->pool)); + wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED); + wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED); + } + +#if !defined(STAGING_CSMT) + if (sub_resource->buffer_object) + wined3d_texture_remove_buffer_object(texture, i, context->gl_info); +#else /* STAGING_CSMT */ + if (sub_resource->buffer) + wined3d_texture_remove_buffer_object(texture, i, context); +#endif /* STAGING_CSMT */ + + if (resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_surface *surface = sub_resource->u.surface; + struct wined3d_renderbuffer_entry *entry, *entry2; + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry) + { + context_gl_resource_released(device, entry->id, TRUE); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); + list_remove(&entry->entry); + HeapFree(GetProcessHeap(), 0, entry); + } + list_init(&surface->renderbuffers); + surface->current_renderbuffer = NULL; + } } + context_release(context); + wined3d_texture_force_reload(texture); wined3d_texture_unload_gl_texture(texture); } -static HRESULT texture2d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, +static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { - struct wined3d_resource *sub_resource; + const struct wined3d_format *format = resource->format; + struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_device *device = resource->device; + unsigned int fmt_flags = resource->format_flags; + struct wined3d_context *context = NULL; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + unsigned int texture_level; + BYTE *base_memory; + BOOL ret; - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", + resource, sub_resource_idx, map_desc, debug_box(box), flags); + + texture = texture_from_resource(resource); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return E_INVALIDARG; - return wined3d_surface_map(surface_from_resource(sub_resource), map_desc, box, flags); + texture_level = sub_resource_idx % texture->level_count; + if (box && FAILED(wined3d_texture_check_box_dimensions(texture, texture_level, box))) + { + WARN("Map box is invalid.\n"); + if (((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && resource->pool == WINED3D_POOL_DEFAULT) + || resource->type != WINED3D_RTYPE_TEXTURE_2D) + return WINED3DERR_INVALIDCALL; + } + + if (!(resource->access_flags & WINED3D_RESOURCE_ACCESS_CPU)) + { + WARN("Trying to map unmappable texture.\n"); + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + return WINED3DERR_INVALIDCALL; + } + + if (texture->flags & WINED3D_TEXTURE_DC_IN_USE) + { + WARN("DC is in use.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (sub_resource->map_count) + { + WARN("Sub-resource is already mapped.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + if (flags & WINED3D_MAP_DISCARD) + { + TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", + wined3d_debug_location(resource->map_binding)); + if ((ret = wined3d_texture_prepare_location(texture, sub_resource_idx, context, resource->map_binding))) + wined3d_texture_validate_location(texture, sub_resource_idx, resource->map_binding); + } + else + { + if (resource->usage & WINED3DUSAGE_DYNAMIC) + WARN_(d3d_perf)("Mapping a dynamic texture without WINED3D_MAP_DISCARD.\n"); + ret = wined3d_texture_load_location(texture, sub_resource_idx, context, resource->map_binding); + } + + if (!ret) + { + ERR("Failed to prepare location.\n"); + context_release(context); + return E_OUTOFMEMORY; + } + + if (!(flags & WINED3D_MAP_READONLY) + && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC))) + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding); + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding); + base_memory = context_map_bo_address(context, &data, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, flags); + TRACE("Base memory pointer %p.\n", base_memory); + + if (context) + context_release(context); + + if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) + { + map_desc->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count; + map_desc->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * map_desc->row_pitch; + } + else + { + wined3d_texture_get_pitch(texture, texture_level, &map_desc->row_pitch, &map_desc->slice_pitch); + } + + if (!box) + { + map_desc->data = base_memory; + } + else + { + if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) + { + /* Compressed textures are block based, so calculate the offset of + * the block that contains the top-left pixel of the mapped box. */ + map_desc->data = base_memory + + (box->front * map_desc->slice_pitch) + + ((box->top / format->block_height) * map_desc->row_pitch) + + ((box->left / format->block_width) * format->block_byte_count); + } + else + { + map_desc->data = base_memory + + (box->front * map_desc->slice_pitch) + + (box->top * map_desc->row_pitch) + + (box->left * format->byte_count); + } + } + + if (texture->swapchain && texture->swapchain->front_buffer == texture) + { + RECT *r = &texture->swapchain->front_buffer_update; + + if (!box) + SetRect(r, 0, 0, resource->width, resource->height); + else + SetRect(r, box->left, box->top, box->right, box->bottom); + TRACE("Mapped front buffer %s.\n", wine_dbgstr_rect(r)); + } + + ++resource->map_count; + ++sub_resource->map_count; + + TRACE("Returning memory %p, row pitch %u, slice pitch %u.\n", + map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); + + return WINED3D_OK; } -static HRESULT texture2d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) +static HRESULT texture_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags) { - struct wined3d_resource *sub_resource; + const struct wined3d_format *format = resource->format; + struct wined3d_texture_sub_resource *sub_resource; + unsigned int fmt_flags = resource->format_flags; + struct wined3d_texture *texture; + unsigned int texture_level; - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) + texture = texture_from_resource(resource); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return E_INVALIDARG; - return wined3d_surface_unmap(surface_from_resource(sub_resource)); + texture_level = sub_resource_idx % texture->level_count; + + if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) + { + info->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count; + info->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * info->row_pitch; + } + else + { + wined3d_texture_get_pitch(texture, texture_level, &info->row_pitch, &info->slice_pitch); + } + + info->size = info->slice_pitch * wined3d_texture_get_level_depth(texture, texture_level); + + return WINED3D_OK; } -#if defined(STAGING_CSMT) -static void wined3d_texture_load_location_invalidated(struct wined3d_resource *resource, DWORD location) +static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) { - ERR("Should not be called on textures.\n"); + struct wined3d_texture_sub_resource *sub_resource; + struct wined3d_device *device = resource->device; + struct wined3d_context *context = NULL; + struct wined3d_texture *texture; + struct wined3d_bo_address data; + + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); + + texture = texture_from_resource(resource); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) + return E_INVALIDARG; + + if (!sub_resource->map_count) + { + WARN("Trying to unmap unmapped sub-resource.\n"); + if (texture->flags & WINED3D_TEXTURE_DC_IN_USE) + return WINED3D_OK; + return WINEDDERR_NOTLOCKED; + } + + if (device->d3d_initialized) + context = context_acquire(device, NULL, 0); + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER); + + if (context) + context_release(context); + + if (texture->swapchain && texture->swapchain->front_buffer == texture) + { + if (!(sub_resource->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB))) + texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain); + } + + --sub_resource->map_count; + if (!--resource->map_count && texture->update_map_binding) + wined3d_texture_update_map_binding(texture); + + return WINED3D_OK; } -/* Context activation is done by the caller. */ -static void wined3d_texture_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - ERR("Should not be called on textures.\n"); -} - -#endif /* STAGING_CSMT */ -static const struct wined3d_resource_ops texture2d_resource_ops = +static const struct wined3d_resource_ops texture_resource_ops = { texture_resource_incref, texture_resource_decref, + texture_resource_preload, wined3d_texture_unload, - texture2d_resource_sub_resource_map, - texture2d_resource_sub_resource_unmap, -#if defined(STAGING_CSMT) - wined3d_texture_load_location_invalidated, - wined3d_texture_load_location, -#endif /* STAGING_CSMT */ + texture_resource_sub_resource_map, + texture_resource_sub_resource_map_info, + texture_resource_sub_resource_unmap, }; -static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, - void *parent, const struct wined3d_parent_ops *parent_ops) +static HRESULT texture1d_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent, + const struct wined3d_parent_ops *parent_ops) { + struct wined3d_device_parent *device_parent = device->device_parent; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_resource_desc surface_desc; - UINT pow2_width, pow2_height; + struct wined3d_surface *surfaces; unsigned int i, j; HRESULT hr; + if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY]) + { + WARN("OpenGL implementation does not support array textures.\n"); + return WINED3DERR_INVALIDCALL; + } + /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ return WINED3DERR_INVALIDCALL; } - /* Non-power2 support. */ - if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) { - pow2_width = desc->width; - pow2_height = desc->height; + WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; } - else - { - /* Find the nearest pow2 match. */ - pow2_width = pow2_height = 1; - while (pow2_width < desc->width) - pow2_width <<= 1; - while (pow2_height < desc->height) - pow2_height <<= 1; - if (pow2_width != desc->width || pow2_height != desc->height) + if (desc->usage & WINED3DUSAGE_DYNAMIC && (desc->pool == WINED3D_POOL_MANAGED + || desc->pool == WINED3D_POOL_SCRATCH)) + { + WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool)); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width)) + { + if (desc->pool == WINED3D_POOL_SCRATCH) { - /* level_count == 0 returns an error as well */ - if (level_count != 1 || desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) - { - if (desc->pool == WINED3D_POOL_SCRATCH) - { - WARN("Creating a scratch mipmapped/cube NPOT texture despite lack of HW support.\n"); - } - else - { - WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n"); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } + WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n"); } + else + { + WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n", + desc->width, desc->height, desc->depth); + return WINED3DERR_INVALIDCALL; + } + } + + if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + { + WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (level_count != 1) + { + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + } + + if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc, + 0, device, parent, parent_ops, &texture_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); + return hr; + } + + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D; + + if (wined3d_texture_use_pbo(texture, gl_info)) + { + wined3d_resource_free_sysmem(&texture->resource); + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + } + + if (level_count > ~(SIZE_T)0 / layer_count + || !(surfaces = wined3d_calloc(level_count * layer_count, sizeof(*surfaces)))) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; + } + + /* Generate all the surfaces. */ + for (i = 0; i < texture->level_count; ++i) + { + for (j = 0; j < texture->layer_count; ++j) + { + struct wined3d_texture_sub_resource *sub_resource; + unsigned int idx = j * texture->level_count + i; + struct wined3d_surface *surface; + + surface = &surfaces[idx]; + surface->container = texture; + surface->texture_target = texture->target; + surface->texture_level = i; + surface->texture_layer = j; + list_init(&surface->renderbuffers); + list_init(&surface->overlays); + + sub_resource = &texture->sub_resources[idx]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + sub_resource->u.surface = surface; + + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create texture1d parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); + return hr; + } + + TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); + + TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface); + } + } + + return WINED3D_OK; +} + +static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + struct wined3d_device_parent *device_parent = device->device_parent; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_surface *surfaces; + UINT pow2_width, pow2_height; + unsigned int i, j; + HRESULT hr; + + if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 + && !gl_info->supported[EXT_TEXTURE_ARRAY]) + { + WARN("OpenGL implementation does not support array textures.\n"); + return WINED3DERR_INVALIDCALL; + } + + /* TODO: It should only be possible to create textures for formats + * that are reported as supported. */ + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + return WINED3DERR_INVALIDCALL; + } + + if (desc->usage & WINED3DUSAGE_DYNAMIC && desc->pool == WINED3D_POOL_MANAGED) + FIXME("Trying to create a managed texture with dynamic usage.\n"); + if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)) + && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE)) + WARN("Creating a mappable texture in the default pool that doesn't specify dynamic usage.\n"); + if (desc->usage & WINED3DUSAGE_RENDERTARGET && desc->pool != WINED3D_POOL_DEFAULT) + FIXME("Trying to create a render target that isn't in the default pool.\n"); + + pow2_width = desc->width; + pow2_height = desc->height; + if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1))) + && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + { + /* level_count == 0 returns an error as well. */ + if (level_count != 1 || layer_count != 1) + { + if (desc->pool != WINED3D_POOL_SCRATCH) + { + WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n"); + return WINED3DERR_INVALIDCALL; + } + + WARN("Creating a scratch mipmapped/cube/array NPOT texture despite lack of HW support.\n"); + } + texture->flags |= WINED3D_TEXTURE_COND_NP2; + + if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) + { + const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage); + + /* TODO: Add support for non-power-of-two compressed textures. */ + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] + & (WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_HEIGHT_SCALE)) + { + FIXME("Compressed or height scaled non-power-of-two (%ux%u) textures are not supported.\n", + desc->width, desc->height); + return WINED3DERR_NOTAVAILABLE; + } + + /* Find the nearest pow2 match. */ + pow2_width = pow2_height = 1; + while (pow2_width < desc->width) + pow2_width <<= 1; + while (pow2_height < desc->height) + pow2_height <<= 1; + texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; + } + } + texture->pow2_width = pow2_width; + texture->pow2_height = pow2_height; + + if ((pow2_width > gl_info->limits.texture_size || pow2_height > gl_info->limits.texture_size) + && (desc->usage & WINED3DUSAGE_TEXTURE)) + { + /* One of four options: + * 1: Do the same as we do with NPOT and scale the texture. (Any + * texture ops would require the texture to be scaled which is + * potentially slow.) + * 2: Set the texture to the maximum size (bad idea). + * 3: WARN and return WINED3DERR_NOTAVAILABLE. + * 4: Create the surface, but allow it to be used only for DirectDraw + * Blts. Some apps (e.g. Swat 3) create textures with a height of + * 16 and a width > 3000 and blt 16x16 letter areas from them to + * the render target. */ + if (desc->pool == WINED3D_POOL_DEFAULT || desc->pool == WINED3D_POOL_MANAGED) + { + WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height); + return WINED3DERR_NOTAVAILABLE; + } + + /* We should never use this surface in combination with OpenGL. */ + TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); } /* Calculate levels for mip mapping. */ @@ -1162,34 +2748,20 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); return WINED3DERR_INVALIDCALL; } if (level_count != 1) { WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); - HeapFree(GetProcessHeap(), 0, texture); -#else /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - - if (level_count != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); -#endif /* STAGING_CSMT */ return WINED3DERR_INVALIDCALL; } } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, - flags, device, parent, parent_ops, &texture2d_resource_ops))) + flags, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ return hr; } @@ -1198,44 +2770,44 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 { texture->pow2_matrix[0] = (float)desc->width; texture->pow2_matrix[5] = (float)desc->height; - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; - texture->target = GL_TEXTURE_RECTANGLE_ARB; - texture->flags |= WINED3D_TEXTURE_COND_NP2; texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS); + texture->target = GL_TEXTURE_RECTANGLE_ARB; } else { - if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) - texture->target = GL_TEXTURE_CUBE_MAP_ARB; - else - texture->target = GL_TEXTURE_2D; - if (desc->width == pow2_width && desc->height == pow2_height) - { - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - } - else if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - { - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - texture->flags |= WINED3D_TEXTURE_COND_NP2; - } - else + if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED) { texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; - texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; } - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; + else + { + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + } + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) + texture->target = GL_TEXTURE_CUBE_MAP_ARB; + else if (layer_count > 1) + texture->target = GL_TEXTURE_2D_ARRAY; + else + texture->target = GL_TEXTURE_2D; + } + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); + + if (wined3d_texture_use_pbo(texture, gl_info)) + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + + if (level_count > ~(SIZE_T)0 / layer_count + || !(surfaces = wined3d_calloc(level_count * layer_count, sizeof(*surfaces)))) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; } - TRACE("xf(%f) yf(%f)\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); /* Generate all the surfaces. */ - surface_desc = *desc; - surface_desc.resource_type = WINED3D_RTYPE_SURFACE; for (i = 0; i < texture->level_count; ++i) { for (j = 0; j < texture->layer_count; ++j) @@ -1249,215 +2821,374 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, }; - GLenum target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target; + struct wined3d_texture_sub_resource *sub_resource; unsigned int idx = j * texture->level_count + i; struct wined3d_surface *surface; - if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, - target, i, j, flags, &surface))) + surface = &surfaces[idx]; + surface->container = texture; + surface->texture_target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target; + surface->texture_level = i; + surface->texture_layer = j; + list_init(&surface->renderbuffers); + list_init(&surface->overlays); + + sub_resource = &texture->sub_resources[idx]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + sub_resource->u.surface = surface; + if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) { - WARN("Failed to create surface, hr %#x.\n", hr); - wined3d_texture_cleanup(texture); + wined3d_texture_validate_location(texture, idx, WINED3D_LOCATION_SYSMEM); + wined3d_texture_invalidate_location(texture, idx, ~WINED3D_LOCATION_SYSMEM); + } + + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create surface parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); return hr; } - texture->sub_resources[idx].resource = &surface->resource; - TRACE("Created surface level %u @ %p.\n", i, surface); + TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); + + TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface); + + if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D)) + { + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (!surface->dc) + { + wined3d_texture_cleanup_sync(texture); + return WINED3DERR_INVALIDCALL; + } + } } - /* Calculate the next mipmap level. */ - surface_desc.width = max(1, surface_desc.width >> 1); - surface_desc.height = max(1, surface_desc.height >> 1); } return WINED3D_OK; } -static void texture3d_sub_resource_load(struct wined3d_resource *sub_resource, - struct wined3d_context *context, BOOL srgb) +/* This call just uploads data, the caller is responsible for binding the + * correct texture. */ +/* Context activation is done by the caller. */ +static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) { - wined3d_volume_load(volume_from_resource(sub_resource), context, srgb); + const struct wined3d_format *format = texture->resource.format; + unsigned int level = sub_resource_idx % texture->level_count; + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int x, y, z, update_w, update_h, update_d; + unsigned int dst_row_pitch, dst_slice_pitch; + unsigned int width, height, depth; + const void *mem = data->addr; + void *converted_mem = NULL; + + TRACE("texture %p, sub_resource_idx %u, context %p, box %s, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n", + texture, sub_resource_idx, context, debug_box(box), + data->buffer_object, data->addr, row_pitch, slice_pitch); + + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); + depth = wined3d_texture_get_level_depth(texture, level); + + if (!box) + { + x = y = z = 0; + update_w = width; + update_h = height; + update_d = depth; + } + else + { + x = box->left; + y = box->top; + z = box->front; + update_w = box->right - box->left; + update_h = box->bottom - box->top; + update_d = box->back - box->front; + } + + if (format->convert) + { + if (data->buffer_object) + ERR("Loading a converted texture from a PBO.\n"); + if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + dst_row_pitch = update_w * format->conv_byte_count; + dst_slice_pitch = dst_row_pitch * update_h; + + converted_mem = wined3d_calloc(update_d, dst_slice_pitch); + format->convert(data->addr, converted_mem, row_pitch, slice_pitch, + dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d); + mem = converted_mem; + } + else + { + wined3d_texture_get_pitch(texture, sub_resource_idx, &dst_row_pitch, &dst_slice_pitch); + if (row_pitch != dst_row_pitch || slice_pitch != dst_slice_pitch) + FIXME("Ignoring row/slice pitch (%u/%u).\n", row_pitch, slice_pitch); + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, + update_w, update_h, update_d, format->glFormat, format->glType, mem)); + checkGLcall("glTexSubImage3D"); + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, converted_mem); } -static void texture3d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource, - const struct wined3d_box *dirty_region) +/* Context activation is done by the caller. */ +static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_bo_address *data) { - wined3d_texture_set_dirty(volume_from_resource(sub_resource)->container); + const struct wined3d_format *format = texture->resource.format; + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (format->convert) + { + FIXME("Attempting to download a converted volume, format %s.\n", + debug_d3dformat(format->id)); + return; + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + } + + gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx, + format->glFormat, format->glType, data->addr); + checkGLcall("glGetTexImage"); + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + } -static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource) +/* Context activation is done by the caller. */ +static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, BOOL dest_is_srgb) { - struct wined3d_volume *volume = volume_from_resource(sub_resource); + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + unsigned int row_pitch, slice_pitch; + struct wined3d_bo_address data; - wined3d_volume_destroy(volume); + /* Optimisations are possible, but the effort should be put into either + * implementing EXT_SRGB_DECODE in the driver or finding out why we + * picked the wrong copy for the original upload and fixing that. + * + * Also keep in mind that we want to avoid using resource.heap_memory + * for DEFAULT pool surfaces. */ + WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n"); + data.buffer_object = 0; + if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size))) + return; + + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb); + texture3d_download_data(texture, sub_resource_idx, context, &data); + wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb); + texture3d_upload_data(texture, sub_resource_idx, context, + NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch); + + HeapFree(GetProcessHeap(), 0, data.addr); } -static void texture3d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) +/* Context activation is done by the caller. */ +static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) { -#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(sub_resource, location); -} - -static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -{ - wined3d_resource_validate_location(sub_resource, location); -#else /* STAGING_CSMT */ - struct wined3d_volume *volume = volume_from_resource(sub_resource); - - wined3d_volume_invalidate_location(volume, location); -} - -static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -{ - struct wined3d_volume *volume = volume_from_resource(sub_resource); - - wined3d_volume_validate_location(volume, location); -#endif /* STAGING_CSMT */ -} - -static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource, - const struct wined3d_context *context, const struct wined3d_sub_resource_data *data) -{ - struct wined3d_volume *volume = volume_from_resource(sub_resource); - struct wined3d_const_bo_address addr; + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; unsigned int row_pitch, slice_pitch; -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(sub_resource, &row_pitch, &slice_pitch); + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) + return FALSE; + + switch (location) + { + case WINED3D_LOCATION_TEXTURE_RGB: + case WINED3D_LOCATION_TEXTURE_SRGB: + if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) + { + struct wined3d_const_bo_address data = {0, texture->resource.heap_memory}; + data.addr += sub_resource->offset; + wined3d_texture_bind_and_dirtify(texture, context, + location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) + { +#if !defined(STAGING_CSMT) + struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; #else /* STAGING_CSMT */ - wined3d_texture_get_pitch(volume->container, volume->texture_level, &row_pitch, &slice_pitch); + struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL}; #endif /* STAGING_CSMT */ - if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch) - FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch); + wined3d_texture_bind_and_dirtify(texture, context, + location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch); + texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + { + texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE); + } + else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) + { + texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE); + } + else + { + FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; - addr.buffer_object = 0; - addr.addr = data->data; + case WINED3D_LOCATION_SYSMEM: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {0, texture->resource.heap_memory}; - wined3d_volume_upload_data(volume, context, &addr); + data.addr += sub_resource->offset; + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture3d_download_data(texture, sub_resource_idx, context, &data); + ++texture->download_count; + } + else + { + FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + case WINED3D_LOCATION_BUFFER: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { +#if !defined(STAGING_CSMT) + struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; +#else /* STAGING_CSMT */ + struct wined3d_bo_address data = {sub_resource->buffer->name, NULL}; +#endif /* STAGING_CSMT */ + + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture3d_download_data(texture, sub_resource_idx, context, &data); + } + else + { + FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + default: + FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + + return TRUE; } static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { - unsigned int sub_count = texture->level_count * texture->layer_count; const struct wined3d_format *format = texture->resource.format; + GLenum internal = srgb ? format->glGammaInternal : format->glInternal; + unsigned int sub_count = texture->level_count * texture->layer_count; const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; wined3d_texture_bind_and_dirtify(texture, context, srgb); - for (i = 0; i < sub_count; ++i) + if (wined3d_texture_use_immutable_storage(texture, gl_info)) { - struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i].resource); - - GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, volume->texture_level, - srgb ? format->glGammaInternal : format->glInternal, - volume->resource.width, volume->resource.height, volume->resource.depth, - 0, format->glFormat, format->glType, NULL)); - checkGLcall("glTexImage3D"); + GL_EXTCALL(glTexStorage3D(GL_TEXTURE_3D, texture->level_count, internal, + wined3d_texture_get_level_width(texture, 0), + wined3d_texture_get_level_height(texture, 0), + wined3d_texture_get_level_depth(texture, 0))); + checkGLcall("glTexStorage3D"); } + else + { + for (i = 0; i < sub_count; ++i) + { + GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, i, internal, + wined3d_texture_get_level_width(texture, i), + wined3d_texture_get_level_height(texture, i), + wined3d_texture_get_level_depth(texture, i), + 0, format->glFormat, format->glType, NULL)); + checkGLcall("glTexImage3D"); + } + } +} + +static void texture3d_cleanup_sub_resources(struct wined3d_texture *texture) +{ } static const struct wined3d_texture_ops texture3d_ops = { - texture3d_sub_resource_load, - texture3d_sub_resource_add_dirty_region, - texture3d_sub_resource_cleanup, - texture3d_sub_resource_invalidate_location, - texture3d_sub_resource_validate_location, - texture3d_sub_resource_upload_data, + texture3d_upload_data, + texture3d_load_location, texture3d_prepare_texture, -}; - -#if !defined(STAGING_CSMT) -BOOL wined3d_texture_check_block_align(const struct wined3d_texture *texture, - unsigned int level, const struct wined3d_box *box) -{ - const struct wined3d_format *format = texture->resource.format; - unsigned int height = max(1, texture->resource.height >> level); - unsigned int width = max(1, texture->resource.width >> level); - unsigned int width_mask, height_mask; - - if ((box->left >= box->right) - || (box->top >= box->bottom) - || (box->right > width) - || (box->bottom > height)) - return FALSE; - - /* This assumes power of two block sizes, but NPOT block sizes would be - * silly anyway. - * - * This also assumes that the format's block depth is 1. */ - width_mask = format->block_width - 1; - height_mask = format->block_height - 1; - - if ((box->left & width_mask) || (box->top & height_mask) - || (box->right & width_mask && box->right != width) - || (box->bottom & height_mask && box->bottom != height)) - return FALSE; - - return TRUE; -} - -#endif /* STAGING_CSMT */ -static HRESULT texture3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_resource *sub_resource; - - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) - return E_INVALIDARG; - - return wined3d_volume_map(volume_from_resource(sub_resource), map_desc, box, flags); -} - -static HRESULT texture3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -{ - struct wined3d_resource *sub_resource; - - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) - return E_INVALIDARG; - - return wined3d_volume_unmap(volume_from_resource(sub_resource)); -} - -static const struct wined3d_resource_ops texture3d_resource_ops = -{ - texture_resource_incref, - texture_resource_decref, - wined3d_texture_unload, - texture3d_resource_sub_resource_map, - texture3d_resource_sub_resource_unmap, + texture3d_cleanup_sub_resources, }; static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - UINT levels, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) + UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent, + const struct wined3d_parent_ops *parent_ops) { + struct wined3d_device_parent *device_parent = device->device_parent; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_resource_desc volume_desc; unsigned int i; HRESULT hr; + if (layer_count != 1) + { + ERR("Invalid layer count for volume texture.\n"); + return E_INVALIDARG; + } + /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); return WINED3DERR_INVALIDCALL; } if (!gl_info->supported[EXT_TEXTURE3D]) { WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); - HeapFree(GetProcessHeap(), 0, texture); -#else /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - - if (!gl_info->supported[EXT_TEXTURE3D]) - { - WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); -#endif /* STAGING_CSMT */ return WINED3DERR_INVALIDCALL; } @@ -1467,41 +3198,26 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); return WINED3DERR_INVALIDCALL; } - if (levels != 1) + if (level_count != 1) { WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - HeapFree(GetProcessHeap(), 0, texture); -#else /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - - if (levels != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); -#endif /* STAGING_CSMT */ return WINED3DERR_INVALIDCALL; } } + if (desc->usage & WINED3DUSAGE_DYNAMIC && (desc->pool == WINED3D_POOL_MANAGED + || desc->pool == WINED3D_POOL_SCRATCH)) + { + WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool)); + return WINED3DERR_INVALIDCALL; + } + if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) { - UINT pow2_w, pow2_h, pow2_d; - pow2_w = 1; - while (pow2_w < desc->width) - pow2_w <<= 1; - pow2_h = 1; - while (pow2_h < desc->height) - pow2_h <<= 1; - pow2_d = 1; - while (pow2_d < desc->depth) - pow2_d <<= 1; - - if (pow2_w != desc->width || pow2_h != desc->height || pow2_d != desc->depth) + if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth)) { if (desc->pool == WINED3D_POOL_SCRATCH) { @@ -1511,21 +3227,15 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct { WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", desc->width, desc->height, desc->depth); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ return WINED3DERR_INVALIDCALL; } } } - if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc, - 0, device, parent, parent_ops, &texture3d_resource_ops))) + if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc, + 0, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); -#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -#endif /* STAGING_CSMT */ return hr; } @@ -1535,26 +3245,32 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct texture->pow2_matrix[15] = 1.0f; texture->target = GL_TEXTURE_3D; + if (wined3d_texture_use_pbo(texture, gl_info)) + { + wined3d_resource_free_sysmem(&texture->resource); + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + } + /* Generate all the surfaces. */ - volume_desc = *desc; - volume_desc.resource_type = WINED3D_RTYPE_VOLUME; for (i = 0; i < texture->level_count; ++i) { - struct wined3d_volume *volume; + struct wined3d_texture_sub_resource *sub_resource; - if (FAILED(hr = wined3d_volume_create(texture, &volume_desc, i, &volume))) + sub_resource = &texture->sub_resources[i]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + + if (FAILED(hr = device_parent->ops->volume_created(device_parent, + texture, i, &sub_resource->parent, &sub_resource->parent_ops))) { - ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); - wined3d_texture_cleanup(texture); + WARN("Failed to create volume parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); return hr; } - texture->sub_resources[i].resource = &volume->resource; + TRACE("parent %p, parent_ops %p.\n", parent, parent_ops); - /* Calculate the next mipmap level. */ - volume_desc.width = max(1, volume_desc.width >> 1); - volume_desc.height = max(1, volume_desc.height >> 1); - volume_desc.depth = max(1, volume_desc.depth >> 1); + TRACE("Created volume level %u.\n", i); } return WINED3D_OK; @@ -1564,44 +3280,80 @@ HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { - struct wined3d_resource *dst_resource, *src_resource = NULL; + struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1}; + struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; + unsigned int dst_format_flags, src_format_flags = 0; + HRESULT hr; TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, " "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n", dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); - if (!(dst_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)) - || dst_resource->type != WINED3D_RTYPE_SURFACE) + if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count + || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) return WINED3DERR_INVALIDCALL; - if (src_texture) + if (src_sub_resource_idx >= src_texture->level_count * src_texture->layer_count + || src_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) + return WINED3DERR_INVALIDCALL; + + dst_format_flags = dst_texture->resource.format_flags; + if (FAILED(hr = wined3d_texture_check_box_dimensions(dst_texture, + dst_sub_resource_idx % dst_texture->level_count, &dst_box))) + return hr; + + src_format_flags = src_texture->resource.format_flags; + if (FAILED(hr = wined3d_texture_check_box_dimensions(src_texture, + src_sub_resource_idx % src_texture->level_count, &src_box))) + return hr; + + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count + || src_texture->sub_resources[src_sub_resource_idx].map_count) { - if (!(src_resource = wined3d_texture_get_sub_resource(src_texture, src_sub_resource_idx)) - || src_resource->type != WINED3D_RTYPE_SURFACE) - return WINED3DERR_INVALIDCALL; +#if !defined(STAGING_CSMT) + WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); + return WINEDDERR_SURFACEBUSY; +#else /* STAGING_CSMT */ + struct wined3d_device *device = dst_texture->resource.device; + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (dst_texture->sub_resources[dst_sub_resource_idx].map_count + || (src_texture && src_texture->sub_resources[src_sub_resource_idx].map_count)) + { + WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n"); + return WINEDDERR_SURFACEBUSY; + } +#endif /* STAGING_CSMT */ } - return wined3d_surface_blt(surface_from_resource(dst_resource), dst_rect, - src_resource ? surface_from_resource(src_resource) : NULL, src_rect, flags, fx, filter); + if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) + != (dst_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + { + WARN("Rejecting depth/stencil blit between incompatible formats.\n"); + return WINED3DERR_INVALIDCALL; + } + + wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx, + &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter); + + return WINED3D_OK; } HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG *x, LONG *y) { - struct wined3d_resource *sub_resource; struct wined3d_surface *surface; TRACE("texture %p, sub_resource_idx %u, x %p, y %p.\n", texture, sub_resource_idx, x, y); if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D - || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) + || sub_resource_idx >= texture->level_count * texture->layer_count) { WARN("Invalid sub-resource specified.\n"); return WINEDDERR_NOTAOVERLAYSURFACE; } - surface = surface_from_resource(sub_resource); + surface = texture->sub_resources[sub_resource_idx].u.surface; if (!surface->overlay_dest) { TRACE("Overlay not visible.\n"); @@ -1621,7 +3373,7 @@ HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture HRESULT CDECL wined3d_texture_set_overlay_position(struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG x, LONG y) { - struct wined3d_resource *sub_resource; + struct wined3d_texture_sub_resource *sub_resource; struct wined3d_surface *surface; LONG w, h; @@ -1634,13 +3386,10 @@ HRESULT CDECL wined3d_texture_set_overlay_position(struct wined3d_texture *textu return WINEDDERR_NOTAOVERLAYSURFACE; } - surface = surface_from_resource(sub_resource); + surface = sub_resource->u.surface; w = surface->overlay_destrect.right - surface->overlay_destrect.left; h = surface->overlay_destrect.bottom - surface->overlay_destrect.top; - surface->overlay_destrect.left = x; - surface->overlay_destrect.top = y; - surface->overlay_destrect.right = x + w; - surface->overlay_destrect.bottom = y + h; + SetRect(&surface->overlay_destrect, x, y, x + w, y + h); return WINED3D_OK; } @@ -1649,7 +3398,7 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags) { - struct wined3d_resource *sub_resource, *dst_sub_resource; + struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource; struct wined3d_surface *surface, *dst_surface; TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, " @@ -1671,17 +3420,21 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un return WINED3DERR_INVALIDCALL; } - surface = surface_from_resource(sub_resource); + surface = sub_resource->u.surface; if (src_rect) surface->overlay_srcrect = *src_rect; else - SetRect(&surface->overlay_srcrect, 0, 0, surface->resource.width, surface->resource.height); + SetRect(&surface->overlay_srcrect, 0, 0, + wined3d_texture_get_level_width(texture, surface->texture_level), + wined3d_texture_get_level_height(texture, surface->texture_level)); - dst_surface = surface_from_resource(dst_sub_resource); + dst_surface = dst_sub_resource->u.surface; if (dst_rect) surface->overlay_destrect = *dst_rect; else - SetRect(&surface->overlay_destrect, 0, 0, dst_surface->resource.width, dst_surface->resource.height); + SetRect(&surface->overlay_destrect, 0, 0, + wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level), + wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level)); if (surface->overlay_dest && (surface->overlay_dest != dst_surface || flags & WINEDDOVER_HIDE)) { @@ -1700,10 +3453,8 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un else if (flags & WINEDDOVER_HIDE) { /* Tests show that the rectangles are erased on hide. */ - surface->overlay_srcrect.left = 0; surface->overlay_srcrect.top = 0; - surface->overlay_srcrect.right = 0; surface->overlay_srcrect.bottom = 0; - surface->overlay_destrect.left = 0; surface->overlay_destrect.top = 0; - surface->overlay_destrect.right = 0; surface->overlay_destrect.bottom = 0; + SetRectEmpty(&surface->overlay_srcrect); + SetRectEmpty(&surface->overlay_destrect); surface->overlay_dest = NULL; } @@ -1722,19 +3473,77 @@ void * CDECL wined3d_texture_get_sub_resource_parent(struct wined3d_texture *tex return NULL; } - return texture->sub_resources[sub_resource_idx].resource->parent; + return texture->sub_resources[sub_resource_idx].parent; +} + +void CDECL wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, + unsigned int sub_resource_idx, void *parent) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + + TRACE("texture %p, sub_resource_idx %u, parent %p.\n", texture, sub_resource_idx, parent); + + if (sub_resource_idx >= sub_count) + { + WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count); + return; + } + + texture->sub_resources[sub_resource_idx].parent = parent; +} + +HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + const struct wined3d_resource *resource; + unsigned int level_idx; + + TRACE("texture %p, sub_resource_idx %u, desc %p.\n", texture, sub_resource_idx, desc); + + if (sub_resource_idx >= sub_count) + { + WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count); + return WINED3DERR_INVALIDCALL; + } + + resource = &texture->resource; + desc->format = resource->format->id; + desc->multisample_type = resource->multisample_type; + desc->multisample_quality = resource->multisample_quality; + desc->usage = resource->usage; + desc->pool = resource->pool; + + level_idx = sub_resource_idx % texture->level_count; + desc->width = wined3d_texture_get_level_width(texture, level_idx); + desc->height = wined3d_texture_get_level_height(texture, level_idx); + desc->depth = wined3d_texture_get_level_depth(texture, level_idx); + desc->size = texture->sub_resources[sub_resource_idx].size; + + return WINED3D_OK; } HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, - const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) + UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { - unsigned int layer_count = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1; struct wined3d_texture *object; HRESULT hr; - TRACE("device %p, desc %p, level_count %u, flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n", - device, desc, level_count, flags, data, parent, parent_ops, texture); + TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, data %p, " + "parent %p, parent_ops %p, texture %p.\n", + device, desc, layer_count, level_count, flags, data, parent, parent_ops, texture); + + if (!layer_count) + { + WARN("Invalid layer count.\n"); + return E_INVALIDARG; + } + if ((desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count != 6) + { + ERR("Invalid layer count %u for legacy cubemap.\n", layer_count); + layer_count = 6; + } if (!level_count) { @@ -1744,7 +3553,8 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct if (desc->multisample_type != WINED3D_MULTISAMPLE_NONE) { - const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format); + const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, + desc->format, desc->usage); if (desc->multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && desc->multisample_quality >= wined3d_popcount(format->multisample_types)) @@ -1769,12 +3579,16 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct switch (desc->resource_type) { + case WINED3D_RTYPE_TEXTURE_1D: + hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops); + break; + case WINED3D_RTYPE_TEXTURE_2D: hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); break; case WINED3D_RTYPE_TEXTURE_3D: - hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops); + hr = volumetexture_init(object, desc, layer_count, level_count, device, parent, parent_ops); break; default: @@ -1786,19 +3600,33 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct if (FAILED(hr)) { WARN("Failed to initialize texture, returning %#x.\n", hr); -#if !defined(STAGING_CSMT) HeapFree(GetProcessHeap(), 0, object); -#endif /* STAGING_CSMT */ return hr; } /* FIXME: We'd like to avoid ever allocating system memory for the texture * in this case. */ - if (data && FAILED(hr = wined3d_texture_upload_data(object, data))) + if (data) { - wined3d_texture_cleanup(object); - HeapFree(GetProcessHeap(), 0, object); - return hr; + unsigned int sub_count = level_count * layer_count; + unsigned int i; + + for (i = 0; i < sub_count; ++i) + { + if (!data[i].data) + { + WARN("Invalid sub-resource data specified for sub-resource %u.\n", i); + wined3d_texture_cleanup_sync(object); + HeapFree(GetProcessHeap(), 0, object); + return E_INVALIDARG; + } + } + + for (i = 0; i < sub_count; ++i) + { + wined3d_device_update_sub_resource(device, &object->resource, + i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch); + } } TRACE("Created texture %p.\n", object); @@ -1810,87 +3638,46 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc) { struct wined3d_device *device = texture->resource.device; -#if defined(STAGING_CSMT) - struct wined3d_resource *sub_resource; + struct wined3d_texture_sub_resource *sub_resource; struct wined3d_surface *surface; -#else /* STAGING_CSMT */ - struct wined3d_context *context = NULL; - struct wined3d_resource *sub_resource; - struct wined3d_surface *surface; - HRESULT hr; -#endif /* STAGING_CSMT */ TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); + if (!(texture->flags & WINED3D_TEXTURE_GET_DC)) + { + WARN("Texture does not support GetDC\n"); + /* Don't touch the DC */ + return WINED3DERR_INVALIDCALL; + } + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return WINED3DERR_INVALIDCALL; - if (sub_resource->type != WINED3D_RTYPE_SURFACE) + if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) { WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type)); return WINED3DERR_INVALIDCALL; } - surface = surface_from_resource(sub_resource); + surface = sub_resource->u.surface; -#if defined(STAGING_CSMT) - if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) - { - WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); - return WINED3DERR_INVALIDCALL; - } - -#endif /* STAGING_CSMT */ - /* Give more detailed info for ddraw. */ - if (surface->flags & SFLAG_DCINUSE) - return WINEDDERR_DCALREADYCREATED; - - /* Can't GetDC if the surface is locked. */ - if (surface->resource.map_count) + if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) return WINED3DERR_INVALIDCALL; -#if defined(STAGING_CSMT) - surface->flags |= SFLAG_DCINUSE; - surface->resource.map_count++; - wined3d_cs_emit_getdc(device->cs, surface); - *dc = surface->hDC; - TRACE("Returning dc %p.\n", *dc); - - return *dc ? WINED3D_OK : WINED3DERR_INVALIDCALL; -} - -HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) -{ - struct wined3d_device *device = texture->resource.device; -#else /* STAGING_CSMT */ - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - /* Create a DIB section if there isn't a dc yet. */ - if (!surface->hDC) + if (!surface->dc) { - if (FAILED(hr = surface_create_dib_section(surface))) - { - if (context) - context_release(context); - return WINED3DERR_INVALIDCALL; - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - || surface->pbo)) - surface->resource.map_binding = WINED3D_LOCATION_DIB; + wined3d_cs_init_object(device->cs, texture2d_create_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } + if (!surface->dc) + return WINED3DERR_INVALIDCALL; - surface_load_location(surface, context, WINED3D_LOCATION_DIB); - surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); + if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) + texture->flags |= WINED3D_TEXTURE_DC_IN_USE; + ++texture->resource.map_count; + ++sub_resource->map_count; - if (context) - context_release(context); - - surface->flags |= SFLAG_DCINUSE; - surface->resource.map_count++; - - *dc = surface->hDC; + *dc = surface->dc; TRACE("Returning dc %p.\n", *dc); return WINED3D_OK; @@ -1899,9 +3686,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) { struct wined3d_device *device = texture->resource.device; - struct wined3d_context *context = NULL; -#endif /* STAGING_CSMT */ - struct wined3d_resource *sub_resource; + struct wined3d_texture_sub_resource *sub_resource; struct wined3d_surface *surface; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -1909,51 +3694,34 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return WINED3DERR_INVALIDCALL; - if (sub_resource->type != WINED3D_RTYPE_SURFACE) + if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) { WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type)); return WINED3DERR_INVALIDCALL; } - surface = surface_from_resource(sub_resource); + surface = sub_resource->u.surface; - if (!(surface->flags & SFLAG_DCINUSE)) - return WINEDDERR_NODC; + if (!(texture->flags & (WINED3D_TEXTURE_GET_DC_LENIENT | WINED3D_TEXTURE_DC_IN_USE))) + return WINED3DERR_INVALIDCALL; - if (surface->hDC != dc) + if (surface->dc != dc) { - WARN("Application tries to release invalid DC %p, surface DC is %p.\n", - dc, surface->hDC); - return WINEDDERR_NODC; + WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc); + return WINED3DERR_INVALIDCALL; } - surface->resource.map_count--; - surface->flags &= ~SFLAG_DCINUSE; - -#if defined(STAGING_CSMT) - wined3d_cs_emit_releasedc(device->cs, surface); -#else /* STAGING_CSMT */ - if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - && surface->resource.map_binding != WINED3D_LOCATION_DIB)) + if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D)) { - /* The game Salammbo modifies the surface contents without mapping the surface between - * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active - * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. - * Do not only copy the DIB to the map location, but also make sure the map location is - * copied back to the DIB in the next getdc call. - * - * The same consideration applies to user memory surfaces. */ - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - surface_load_location(surface, context, surface->resource.map_binding); - surface_invalidate_location(surface, WINED3D_LOCATION_DIB); - if (context) - context_release(context); + wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface); + device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); } -#endif /* STAGING_CSMT */ + + --sub_resource->map_count; + if (!--texture->resource.map_count && texture->update_map_binding) + wined3d_texture_update_map_binding(texture); + if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT)) + texture->flags &= ~WINED3D_TEXTURE_DC_IN_USE; return WINED3D_OK; } diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 4f8c0ae89cd..979ce88a7f2 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -93,8 +93,7 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, /* Hmm? */ {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, - {WINED3DFMT_R16G16_SINT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0}, - {WINED3DFMT_R16G16B16A16_SINT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0}, + {WINED3DFMT_R11G11B10_FLOAT, 11, 11, 10, 0, 0, 11, 22, 0, 4, 0, 0}, /* Palettized formats */ {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0}, {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, @@ -120,6 +119,8 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0}, {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0}, + {WINED3DFMT_R10G10B10X2_UINT, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, + {WINED3DFMT_R10G10B10X2_SNORM, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0}, {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0}, /* Depth stencil formats */ {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, @@ -130,7 +131,6 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0}, {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0}, {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8}, - {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, @@ -144,6 +144,8 @@ static const struct wined3d_format_channels formats[] = /* Unsure about them, could not find a Windows driver that supports them */ {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0}, + /* DirectX 10 HDR formats */ + {WINED3DFMT_R9G9B9E5_SHAREDEXP, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, /* Typeless */ {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0}, {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0}, @@ -163,6 +165,8 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_BC3_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_BC4_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_BC5_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {WINED3DFMT_BC6H_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {WINED3DFMT_BC7_TYPELESS, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_B8G8R8A8_TYPELESS, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0}, {WINED3DFMT_B8G8R8X8_TYPELESS, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0}, }; @@ -177,6 +181,7 @@ enum wined3d_channel_type WINED3D_CHANNEL_TYPE_FLOAT, WINED3D_CHANNEL_TYPE_DEPTH, WINED3D_CHANNEL_TYPE_STENCIL, + WINED3D_CHANNEL_TYPE_UNUSED, }; struct wined3d_typed_format_info @@ -196,50 +201,114 @@ struct wined3d_typed_format_info * F - WINED3D_CHANNEL_TYPE_FLOAT * D - WINED3D_CHANNEL_TYPE_DEPTH * S - WINED3D_CHANNEL_TYPE_STENCIL + * X - WINED3D_CHANNEL_TYPE_UNUSED */ static const struct wined3d_typed_format_info typed_formats[] = { - {WINED3DFMT_R32G32B32A32_UINT, WINED3DFMT_R32G32B32A32_TYPELESS, "UUUU"}, - {WINED3DFMT_R32G32B32A32_SINT, WINED3DFMT_R32G32B32A32_TYPELESS, "IIII"}, - {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_R32G32B32A32_TYPELESS, "FFFF"}, - {WINED3DFMT_R32G32B32_UINT, WINED3DFMT_R32G32B32_TYPELESS, "UUU"}, - {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_R32G32B32_TYPELESS, "FFF"}, - {WINED3DFMT_R16G16B16A16_UNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "uuuu"}, - {WINED3DFMT_R16G16B16A16_SNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "iiii"}, - {WINED3DFMT_R16G16B16A16_SINT, WINED3DFMT_R16G16B16A16_TYPELESS, "IIII"}, - {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_R16G16B16A16_TYPELESS, "FFFF"}, - {WINED3DFMT_R32G32_UINT, WINED3DFMT_R32G32_TYPELESS, "UU"}, - {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_R32G32_TYPELESS, "FF"}, - {WINED3DFMT_R10G10B10A2_SNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "iiii"}, - {WINED3DFMT_R10G10B10A2_UINT, WINED3DFMT_R10G10B10A2_TYPELESS, "UUUU"}, - {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "uuuu"}, - {WINED3DFMT_R8G8B8A8_UINT, WINED3DFMT_R8G8B8A8_TYPELESS, "UUUU"}, - {WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_R8G8B8A8_TYPELESS, "IIII"}, - {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, - {WINED3DFMT_R16G16_UNORM, WINED3DFMT_R16G16_TYPELESS, "uu"}, - {WINED3DFMT_R16G16_SNORM, WINED3DFMT_R16G16_TYPELESS, "ii"}, - {WINED3DFMT_R16G16_SINT, WINED3DFMT_R16G16_TYPELESS, "II"}, - {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_R16G16_TYPELESS, "FF"}, - {WINED3DFMT_R32_UINT, WINED3DFMT_R32_TYPELESS, "U"}, - {WINED3DFMT_R32_FLOAT, WINED3DFMT_R32_TYPELESS, "F"}, - {WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_R24G8_TYPELESS, "DS"}, - {WINED3DFMT_R8G8_SNORM, WINED3DFMT_R8G8_TYPELESS, "ii"}, - {WINED3DFMT_R8G8_UNORM, WINED3DFMT_R8G8_TYPELESS, "uu"}, - {WINED3DFMT_R16_UNORM, WINED3DFMT_R16_TYPELESS, "u"}, - {WINED3DFMT_R16_UINT, WINED3DFMT_R16_TYPELESS, "U"}, - {WINED3DFMT_R16_FLOAT, WINED3DFMT_R16_TYPELESS, "F"}, - {WINED3DFMT_R8_UNORM, WINED3DFMT_R8_TYPELESS, "u"}, - {WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_TYPELESS, ""}, - {WINED3DFMT_BC1_UNORM, WINED3DFMT_BC1_TYPELESS, ""}, - {WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_TYPELESS, ""}, - {WINED3DFMT_BC2_UNORM, WINED3DFMT_BC2_TYPELESS, ""}, - {WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_TYPELESS, ""}, - {WINED3DFMT_BC3_UNORM, WINED3DFMT_BC3_TYPELESS, ""}, - {WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, - {WINED3DFMT_B8G8R8X8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_TYPELESS, "uuu"}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8X8_TYPELESS, "uuu"}, + {WINED3DFMT_R32G32B32A32_UINT, WINED3DFMT_R32G32B32A32_TYPELESS, "UUUU"}, + {WINED3DFMT_R32G32B32A32_SINT, WINED3DFMT_R32G32B32A32_TYPELESS, "IIII"}, + {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_R32G32B32A32_TYPELESS, "FFFF"}, + {WINED3DFMT_R32G32B32_UINT, WINED3DFMT_R32G32B32_TYPELESS, "UUU"}, + {WINED3DFMT_R32G32B32_SINT, WINED3DFMT_R32G32B32_TYPELESS, "III"}, + {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_R32G32B32_TYPELESS, "FFF"}, + {WINED3DFMT_R16G16B16A16_UNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "uuuu"}, + {WINED3DFMT_R16G16B16A16_SNORM, WINED3DFMT_R16G16B16A16_TYPELESS, "iiii"}, + {WINED3DFMT_R16G16B16A16_UINT, WINED3DFMT_R16G16B16A16_TYPELESS, "UUUU"}, + {WINED3DFMT_R16G16B16A16_SINT, WINED3DFMT_R16G16B16A16_TYPELESS, "IIII"}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_R16G16B16A16_TYPELESS, "FFFF"}, + {WINED3DFMT_R32G32_UINT, WINED3DFMT_R32G32_TYPELESS, "UU"}, + {WINED3DFMT_R32G32_SINT, WINED3DFMT_R32G32_TYPELESS, "II"}, + {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_R32G32_TYPELESS, "FF"}, + {WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, WINED3DFMT_R32G8X24_TYPELESS, "DX"}, + {WINED3DFMT_X32_TYPELESS_G8X24_UINT, WINED3DFMT_R32G8X24_TYPELESS, "XS"}, + {WINED3DFMT_D32_FLOAT_S8X24_UINT, WINED3DFMT_R32G8X24_TYPELESS, "DS"}, + {WINED3DFMT_R10G10B10A2_SNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "iiii"}, + {WINED3DFMT_R10G10B10A2_UINT, WINED3DFMT_R10G10B10A2_TYPELESS, "UUUU"}, + {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_R10G10B10A2_TYPELESS, "uuuu"}, + {WINED3DFMT_R8G8B8A8_UINT, WINED3DFMT_R8G8B8A8_TYPELESS, "UUUU"}, + {WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_R8G8B8A8_TYPELESS, "IIII"}, + {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, + {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"}, + {WINED3DFMT_R16G16_UNORM, WINED3DFMT_R16G16_TYPELESS, "uu"}, + {WINED3DFMT_R16G16_SNORM, WINED3DFMT_R16G16_TYPELESS, "ii"}, + {WINED3DFMT_R16G16_UINT, WINED3DFMT_R16G16_TYPELESS, "UU"}, + {WINED3DFMT_R16G16_SINT, WINED3DFMT_R16G16_TYPELESS, "II"}, + {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_R16G16_TYPELESS, "FF"}, + {WINED3DFMT_D32_FLOAT, WINED3DFMT_R32_TYPELESS, "D"}, + {WINED3DFMT_R32_FLOAT, WINED3DFMT_R32_TYPELESS, "F"}, + {WINED3DFMT_R32_UINT, WINED3DFMT_R32_TYPELESS, "U"}, + {WINED3DFMT_R32_SINT, WINED3DFMT_R32_TYPELESS, "I"}, + {WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_R24G8_TYPELESS, "DX"}, + {WINED3DFMT_X24_TYPELESS_G8_UINT, WINED3DFMT_R24G8_TYPELESS, "XS"}, + {WINED3DFMT_D24_UNORM_S8_UINT, WINED3DFMT_R24G8_TYPELESS, "DS"}, + {WINED3DFMT_R8G8_SNORM, WINED3DFMT_R8G8_TYPELESS, "ii"}, + {WINED3DFMT_R8G8_UNORM, WINED3DFMT_R8G8_TYPELESS, "uu"}, + {WINED3DFMT_R8G8_UINT, WINED3DFMT_R8G8_TYPELESS, "UU"}, + {WINED3DFMT_R8G8_SINT, WINED3DFMT_R8G8_TYPELESS, "II"}, + {WINED3DFMT_D16_UNORM, WINED3DFMT_R16_TYPELESS, "D"}, + {WINED3DFMT_R16_UNORM, WINED3DFMT_R16_TYPELESS, "u"}, + {WINED3DFMT_R16_SNORM, WINED3DFMT_R16_TYPELESS, "i"}, + {WINED3DFMT_R16_UINT, WINED3DFMT_R16_TYPELESS, "U"}, + {WINED3DFMT_R16_SINT, WINED3DFMT_R16_TYPELESS, "I"}, + {WINED3DFMT_R16_FLOAT, WINED3DFMT_R16_TYPELESS, "F"}, + {WINED3DFMT_R8_UNORM, WINED3DFMT_R8_TYPELESS, "u"}, + {WINED3DFMT_R8_SNORM, WINED3DFMT_R8_TYPELESS, "i"}, + {WINED3DFMT_R8_UINT, WINED3DFMT_R8_TYPELESS, "U"}, + {WINED3DFMT_R8_SINT, WINED3DFMT_R8_TYPELESS, "I"}, + {WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_TYPELESS, ""}, + {WINED3DFMT_BC1_UNORM, WINED3DFMT_BC1_TYPELESS, ""}, + {WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_TYPELESS, ""}, + {WINED3DFMT_BC2_UNORM, WINED3DFMT_BC2_TYPELESS, ""}, + {WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_TYPELESS, ""}, + {WINED3DFMT_BC3_UNORM, WINED3DFMT_BC3_TYPELESS, ""}, + {WINED3DFMT_BC4_UNORM, WINED3DFMT_BC4_TYPELESS, ""}, + {WINED3DFMT_BC5_UNORM, WINED3DFMT_BC5_TYPELESS, ""}, + {WINED3DFMT_BC5_SNORM, WINED3DFMT_BC5_TYPELESS, ""}, + {WINED3DFMT_BC6H_UF16, WINED3DFMT_BC6H_TYPELESS, ""}, + {WINED3DFMT_BC6H_SF16, WINED3DFMT_BC6H_TYPELESS, ""}, + {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_TYPELESS, ""}, + {WINED3DFMT_BC7_UNORM, WINED3DFMT_BC7_TYPELESS, ""}, + {WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8A8_TYPELESS, "uuuu"}, + {WINED3DFMT_B8G8R8X8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_TYPELESS, "uuuX"}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8X8_TYPELESS, "uuuX"}, +}; + +struct wined3d_typeless_format_depth_stencil_info +{ + enum wined3d_format_id typeless_id; + enum wined3d_format_id depth_stencil_id; + enum wined3d_format_id depth_view_id; + enum wined3d_format_id stencil_view_id; +}; + +static const struct wined3d_typeless_format_depth_stencil_info typeless_depth_stencil_formats[] = +{ + {WINED3DFMT_R32G8X24_TYPELESS, WINED3DFMT_D32_FLOAT_S8X24_UINT, + WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, WINED3DFMT_X32_TYPELESS_G8X24_UINT}, + {WINED3DFMT_R24G8_TYPELESS, WINED3DFMT_D24_UNORM_S8_UINT, + WINED3DFMT_R24_UNORM_X8_TYPELESS, WINED3DFMT_X24_TYPELESS_G8_UINT}, + {WINED3DFMT_R32_TYPELESS, WINED3DFMT_D32_FLOAT}, + {WINED3DFMT_R16_TYPELESS, WINED3DFMT_D16_UNORM}, +}; + +struct wined3d_format_ddi_info +{ + enum wined3d_format_id id; + D3DDDIFORMAT ddi_format; +}; + +static const struct wined3d_format_ddi_info ddi_formats[] = +{ + {WINED3DFMT_B8G8R8_UNORM, D3DDDIFMT_R8G8B8}, + {WINED3DFMT_B8G8R8A8_UNORM, D3DDDIFMT_A8R8G8B8}, + {WINED3DFMT_B8G8R8X8_UNORM, D3DDDIFMT_X8R8G8B8}, + {WINED3DFMT_B5G6R5_UNORM, D3DDDIFMT_R5G6B5}, + {WINED3DFMT_B5G5R5X1_UNORM, D3DDDIFMT_X1R5G5B5}, + {WINED3DFMT_B5G5R5A1_UNORM, D3DDDIFMT_A1R5G5B5}, + {WINED3DFMT_B4G4R4A4_UNORM, D3DDDIFMT_A4R4G4B4}, + {WINED3DFMT_B4G4R4X4_UNORM, D3DDDIFMT_X4R4G4B4}, + {WINED3DFMT_P8_UINT, D3DDDIFMT_P8}, }; struct wined3d_format_base_flags @@ -253,21 +322,12 @@ struct wined3d_format_base_flags * resource size. */ static const struct wined3d_format_base_flags format_base_flags[] = { - {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH}, - {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH}, - {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, - {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH}, + {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH}, + {WINED3DFMT_R11G11B10_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_D32_FLOAT_S8X24_UINT, WINED3DFMT_FLAG_FLOAT}, }; struct wined3d_format_block_info @@ -289,6 +349,12 @@ static const struct wined3d_format_block_info format_block_info[] = {WINED3DFMT_BC1_UNORM, 4, 4, 8, TRUE}, {WINED3DFMT_BC2_UNORM, 4, 4, 16, TRUE}, {WINED3DFMT_BC3_UNORM, 4, 4, 16, TRUE}, + {WINED3DFMT_BC4_UNORM, 4, 4, 8, TRUE}, + {WINED3DFMT_BC5_UNORM, 4, 4, 16, TRUE}, + {WINED3DFMT_BC5_SNORM, 4, 4, 16, TRUE}, + {WINED3DFMT_BC6H_UF16, 4, 4, 16, TRUE}, + {WINED3DFMT_BC6H_SF16, 4, 4, 16, TRUE}, + {WINED3DFMT_BC7_UNORM, 4, 4, 16, TRUE}, {WINED3DFMT_ATI1N, 4, 4, 8, FALSE}, {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, @@ -299,36 +365,48 @@ struct wined3d_format_vertex_info { enum wined3d_format_id id; enum wined3d_ffp_emit_idx emit_idx; - GLint component_count; + unsigned int component_count; GLenum gl_vtx_type; - GLint gl_vtx_format; GLboolean gl_normalized; - unsigned int component_size; + enum wined3d_gl_extension extension; }; static const struct wined3d_format_vertex_info format_vertex_info[] = { - {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)}, - {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)}, - {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)}, - {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, - {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)}, - {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)}, - {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, - {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)}, - {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)}, - {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)}, - {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)}, - {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)}, - {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)}, - {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)}, - {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}, - {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)}, - {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)}, - {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)}, - {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)}, + {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, GL_FALSE}, + {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, GL_FALSE}, + {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, GL_FALSE}, + {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, GL_FALSE}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE }, + {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, GL_FALSE}, + {WINED3DFMT_R16G16_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_SHORT, GL_FALSE}, + {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, GL_FALSE}, + {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, GL_FALSE}, + {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, GL_TRUE }, + {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, GL_TRUE }, + {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, GL_TRUE }, + {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, GL_TRUE }, + {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, GL_TRUE }, + {WINED3DFMT_R10G10B10X2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, GL_FALSE}, + {WINED3DFMT_R10G10B10X2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, GL_TRUE }, + {WINED3DFMT_R10G10B10A2_UNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, + ARB_VERTEX_TYPE_2_10_10_10_REV}, + {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_HALF_FLOAT, GL_FALSE}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_HALF_FLOAT, GL_FALSE}, + {WINED3DFMT_R8G8B8A8_SNORM, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_TRUE }, + {WINED3DFMT_R8G8B8A8_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_BYTE, GL_FALSE}, + {WINED3DFMT_R16G16B16A16_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_SHORT, GL_FALSE}, + {WINED3DFMT_R8_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_BYTE, GL_FALSE}, + {WINED3DFMT_R8_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_BYTE, GL_FALSE}, + {WINED3DFMT_R16_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_SHORT, GL_FALSE}, + {WINED3DFMT_R16_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_SHORT, GL_FALSE}, + {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, GL_FALSE}, + {WINED3DFMT_R32_SINT, WINED3D_FFP_EMIT_INVALID, 1, GL_INT, GL_FALSE}, + {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, GL_FALSE}, + {WINED3DFMT_R32G32_SINT, WINED3D_FFP_EMIT_INVALID, 2, GL_INT, GL_FALSE}, + {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, GL_FALSE}, + {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, GL_FALSE}, + {WINED3DFMT_R32G32B32A32_SINT, WINED3D_FFP_EMIT_INVALID, 4, GL_INT, GL_FALSE}, }; struct wined3d_format_texture_info @@ -747,6 +825,26 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p } } +static void convert_x8_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, + UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth) +{ + unsigned int x, y, z; + + for (z = 0; z < depth; ++z) + { + for (y = 0; y < height; ++y) + { + const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch); + DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch); + + for (x = 0; x < width; ++x) + { + dest[x] = source[x] << 8 | source[x] >> 16; + } + } + } +} + static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color) { /* FIXME: Is this really how color keys are supposed to work? I think it @@ -984,30 +1082,46 @@ static const struct wined3d_format_texture_info format_texture_info[] = * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big * endian machine */ - {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, + {WINED3DFMT_UYVY, GL_RG8, GL_RG8, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_UYVY, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE8_ALPHA8, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, APPLE_YCBCR_422, NULL}, - {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, + {WINED3DFMT_YUY2, GL_RG8, GL_RG8, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_YUY2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE8_ALPHA8, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, APPLE_YCBCR_422, NULL}, - {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0, + {WINED3DFMT_YV12, GL_R8, GL_R8, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_YV12, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, - {WINED3DFMT_NV12, GL_ALPHA, GL_ALPHA, 0, + WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_NV12, GL_R8, GL_R8, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_NV12, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING @@ -1048,6 +1162,36 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, + {WINED3DFMT_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_RGTC, NULL}, + {WINED3DFMT_BC5_UNORM, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_RGTC, NULL}, + {WINED3DFMT_BC5_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_COMPRESSED_SIGNED_RG_RGTC2, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_RGTC, NULL}, + {WINED3DFMT_BC6H_UF16, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, 0, + GL_RGB, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_BPTC, NULL}, + {WINED3DFMT_BC6H_SF16, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, 0, + GL_RGB, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_BPTC, NULL}, + {WINED3DFMT_BC7_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + ARB_TEXTURE_COMPRESSION_BPTC, NULL}, /* IEEE formats */ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, GL_RED, GL_FLOAT, 0, @@ -1095,11 +1239,19 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, ARB_TEXTURE_FLOAT, NULL}, + {WINED3DFMT_R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, 0, + GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET, + EXT_PACKED_FLOAT}, /* Palettized formats */ + {WINED3DFMT_P8_UINT, GL_R8, GL_R8, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + 0, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_P8_UINT, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - 0, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, /* Standard ARGB formats */ {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0, GL_BGR, GL_UNSIGNED_BYTE, 0, @@ -1149,10 +1301,14 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_A8_UNORM, GL_R8, GL_R8, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, @@ -1170,11 +1326,11 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_8_8_8_8_REV, 0, - WINED3DFMT_FLAG_TEXTURE, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, ARB_TEXTURE_RGB10_A2UI, NULL}, {WINED3DFMT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, 0, GL_RGBA_INTEGER, GL_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_INTEGER, NULL}, {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, @@ -1201,7 +1357,48 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8_UNORM, GL_RG8, GL_RG8, 0, GL_RG, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R8G8_UINT, GL_RG8UI, GL_RG8UI, 0, + GL_RG_INTEGER, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R8G8_SINT, GL_RG8I, GL_RG8I, 0, + GL_RG_INTEGER, GL_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, 0, + GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + EXT_TEXTURE_INTEGER, NULL}, + {WINED3DFMT_R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, 0, + GL_RGBA_INTEGER, GL_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + EXT_TEXTURE_INTEGER, NULL}, + {WINED3DFMT_R32G32_UINT, GL_RG32UI, GL_RG32UI, 0, + GL_RG_INTEGER, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R32G32_SINT, GL_RG32I, GL_RG32I, 0, + GL_RG_INTEGER, GL_INT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R16G16_UINT, GL_RG16UI, GL_RG16UI, 0, + GL_RG_INTEGER, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R16G16_SINT, GL_RG16I, GL_RG16I, 0, + GL_RG_INTEGER, GL_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R32_UINT, GL_R32UI, GL_R32UI, 0, + GL_RED_INTEGER, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R32_SINT, GL_R32I, GL_R32I, 0, + GL_RED_INTEGER, GL_INT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16_UNORM, GL_R16, GL_R16, 0, GL_RED, GL_UNSIGNED_SHORT, 0, @@ -1210,23 +1407,56 @@ static const struct wined3d_format_texture_info format_texture_info[] = ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16_UINT, GL_R16UI, GL_R16UI, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0, - WINED3DFMT_FLAG_TEXTURE, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R16_SINT, GL_R16I, GL_R16I, 0, + GL_RED_INTEGER, GL_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R8_UINT, GL_R8UI, GL_R8UI, 0, + GL_RED_INTEGER, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R8_SINT, GL_R8I, GL_R8I, 0, + GL_RED_INTEGER, GL_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, ARB_TEXTURE_RG, NULL}, /* Luminance */ {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_L8_UNORM, GL_R8, GL_R8, 0, + GL_RED, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_L8A8_UNORM, GL_RG8, GL_RG8, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_L4A4_UNORM, GL_RG8, GL_RG8, 0, + GL_RG, GL_UNSIGNED_BYTE, 2, + WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, convert_l4a4_unorm}, {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, convert_l4a4_unorm}, + WINED3D_GL_LEGACY_CONTEXT, convert_l4a4_unorm}, + {WINED3DFMT_L16_UNORM, GL_R16, GL_R16, 0, + GL_RED, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, + GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3D_GL_LEGACY_CONTEXT, NULL}, /* Bump mapping stuff */ {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0, GL_BGR, GL_UNSIGNED_BYTE, 3, @@ -1241,7 +1471,7 @@ static const struct wined3d_format_texture_info format_texture_info[] = {WINED3DFMT_R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, 0, GL_RG, GL_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_BUMPMAP, + | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, EXT_TEXTURE_SNORM, NULL}, {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, @@ -1281,7 +1511,7 @@ static const struct wined3d_format_texture_info format_texture_info[] = {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, 0, GL_RGBA, GL_BYTE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_BUMPMAP, + | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, EXT_TEXTURE_SNORM, NULL}, {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0, GL_BGR, GL_UNSIGNED_SHORT, 6, @@ -1296,7 +1526,22 @@ static const struct wined3d_format_texture_info format_texture_info[] = {WINED3DFMT_R16G16_SNORM, GL_RG16_SNORM, GL_RG16_SNORM, 0, GL_RG, GL_SHORT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING - | WINED3DFMT_FLAG_BUMPMAP, + | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_BUMPMAP, + EXT_TEXTURE_SNORM, NULL}, + {WINED3DFMT_R16G16B16A16_SNORM, GL_RGBA16_SNORM, GL_RGBA16_SNORM, 0, + GL_RGBA, GL_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, + EXT_TEXTURE_SNORM, NULL}, + {WINED3DFMT_R16_SNORM, GL_R16_SNORM, GL_R16_SNORM, 0, + GL_RED, GL_SHORT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, + EXT_TEXTURE_SNORM, NULL}, + {WINED3DFMT_R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, 0, + GL_RED, GL_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_SNORM, NULL}, /* Depth stencil formats */ {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, @@ -1343,14 +1588,14 @@ static const struct wined3d_format_texture_info format_texture_info[] = | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, ARB_FRAMEBUFFER_OBJECT, NULL}, {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, WINED3DFMT_FLAG_DEPTH, - WINED3D_GL_EXT_NONE, NULL}, + WINED3D_GL_EXT_NONE, convert_x8_d24_unorm}, {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, - ARB_DEPTH_TEXTURE, NULL}, + ARB_DEPTH_TEXTURE, convert_x8_d24_unorm}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, @@ -1372,26 +1617,30 @@ static const struct wined3d_format_texture_info format_texture_info[] = WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, ARB_DEPTH_TEXTURE, NULL}, - {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, - GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, ARB_DEPTH_BUFFER_FLOAT, NULL}, + {WINED3DFMT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, + GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_BUFFER_FLOAT, NULL}, {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float}, {WINED3DFMT_R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, 0, - WINED3DFMT_FLAG_TEXTURE, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_INTEGER, NULL}, {WINED3DFMT_R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, 0, GL_RGBA_INTEGER, GL_INT, 0, - WINED3DFMT_FLAG_TEXTURE, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, EXT_TEXTURE_INTEGER, NULL}, + {WINED3DFMT_R24_UNORM_X8_TYPELESS, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH, + ARB_DEPTH_TEXTURE, NULL}, /* Vendor-specific formats */ {WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0, GL_RED, GL_UNSIGNED_BYTE, 0, @@ -1427,6 +1676,11 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE, ARB_FRAMEBUFFER_OBJECT, NULL}, + /* DirectX 10 HDR formats */ + {WINED3DFMT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5_EXT, GL_RGB9_E5_EXT, 0, + GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV_EXT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + EXT_TEXTURE_SHARED_EXPONENT, NULL}, }; struct wined3d_format_srgb_info @@ -1462,6 +1716,27 @@ static inline int get_format_idx(enum wined3d_format_id format_id) return -1; } +static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_info, + enum wined3d_format_id format_id) +{ + int fmt_idx; + + if ((fmt_idx = get_format_idx(format_id)) == -1) + { + ERR("Format %s (%#x) not found.\n", debug_d3dformat(format_id), format_id); + return NULL; + } + + return &gl_info->formats[fmt_idx]; +} + +static void copy_format(struct wined3d_format *dst_format, const struct wined3d_format *src_format) +{ + enum wined3d_format_id id = dst_format->id; + *dst_format = *src_format; + dst_format->id = id; +} + static void format_set_flag(struct wined3d_format *format, unsigned int flag) { unsigned int i; @@ -1496,6 +1771,8 @@ static enum wined3d_channel_type map_channel_type(char t) return WINED3D_CHANNEL_TYPE_DEPTH; case 'S': return WINED3D_CHANNEL_TYPE_STENCIL; + case 'X': + return WINED3D_CHANNEL_TYPE_UNUSED; default: ERR("Invalid channel type '%c'.\n", t); return WINED3D_CHANNEL_TYPE_NONE; @@ -1504,11 +1781,12 @@ static enum wined3d_channel_type map_channel_type(char t) static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) { + struct wined3d_format *format; unsigned int i, j; gl_info->format_count = WINED3D_FORMAT_COUNT; - if (!(gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - gl_info->format_count * sizeof(*gl_info->formats)))) + if (!(gl_info->formats = wined3d_calloc(gl_info->format_count + + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats)))) { ERR("Failed to allocate memory.\n"); return FALSE; @@ -1516,17 +1794,8 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) for (i = 0; i < ARRAY_SIZE(formats); ++i) { - struct wined3d_format *format; - int fmt_idx; - - fmt_idx = get_format_idx(formats[i].id); - if (fmt_idx == -1) - { - ERR("Could not allocate index for format %s %#x.\n", - debug_d3dformat(formats[i].id), formats[i].id); + if (!(format = get_format_internal(gl_info, formats[i].id))) goto fail; - } - format = &gl_info->formats[fmt_idx]; format->id = formats[i].id; format->red_size = formats[i].red_size; @@ -1548,26 +1817,13 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) { const struct wined3d_format *typeless_format; - struct wined3d_format *format; DWORD flags = 0; - int fmt_idx; - fmt_idx = get_format_idx(typed_formats[i].id); - if (fmt_idx == -1) - { - ERR("Could not allocate index for format %s %#x.\n", - debug_d3dformat(typed_formats[i].id), typed_formats[i].id); + if (!(format = get_format_internal(gl_info, typed_formats[i].id))) goto fail; - } - format = &gl_info->formats[fmt_idx]; - typeless_format = wined3d_get_format(gl_info, typed_formats[i].typeless_id); - if (typeless_format->id == WINED3DFMT_UNKNOWN) - { - ERR("Typeless format %s (%#x) not found.\n", - debug_d3dformat(typed_formats[i].typeless_id), typed_formats[i].typeless_id); + if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) goto fail; - } format->id = typed_formats[i].id; format->red_size = typeless_format->red_size; @@ -1584,6 +1840,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) format->block_width = typeless_format->block_width; format->block_height = typeless_format->block_height; format->block_byte_count = typeless_format->block_byte_count; + format->typeless_id = typeless_format->id; for (j = 0; j < strlen(typed_formats[i].channels); ++j) { @@ -1592,23 +1849,31 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) flags |= WINED3DFMT_FLAG_INTEGER; if (channel_type == WINED3D_CHANNEL_TYPE_FLOAT) flags |= WINED3DFMT_FLAG_FLOAT; + + if (channel_type == WINED3D_CHANNEL_TYPE_DEPTH && !format->depth_size) + { + format->depth_size = format->red_size; + format->red_size = format->red_offset = 0; + } } format_set_flag(format, flags); } + for (i = 0; i < ARRAY_SIZE(ddi_formats); ++i) + { + if (!(format = get_format_internal(gl_info, ddi_formats[i].id))) + goto fail; + + format->ddi_format = ddi_formats[i].ddi_format; + } + for (i = 0; i < ARRAY_SIZE(format_base_flags); ++i) { - int fmt_idx = get_format_idx(format_base_flags[i].id); - - if (fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id); + if (!(format = get_format_internal(gl_info, format_base_flags[i].id))) goto fail; - } - format_set_flag(&gl_info->formats[fmt_idx], format_base_flags[i].flags); + format_set_flag(format, format_base_flags[i].flags); } return TRUE; @@ -1620,27 +1885,20 @@ fail: static BOOL init_format_block_info(struct wined3d_gl_info *gl_info) { + struct wined3d_format *format; unsigned int i; - for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i) + for (i = 0; i < ARRAY_SIZE(format_block_info); ++i) { - struct wined3d_format *format; - int fmt_idx = get_format_idx(format_block_info[i].id); - - if (fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(format_block_info[i].id), format_block_info[i].id); + if (!(format = get_format_internal(gl_info, format_block_info[i].id))) return FALSE; - } - format = &gl_info->formats[fmt_idx]; format->block_width = format_block_info[i].block_width; format->block_height = format_block_info[i].block_height; format->block_byte_count = format_block_info[i].block_byte_count; - format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_BLOCKS); + format_set_flag(format, WINED3DFMT_FLAG_BLOCKS); if (!format_block_info[i].verify) - format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_BLOCKS_NO_VERIFY); + format_set_flag(format, WINED3DFMT_FLAG_BLOCKS_NO_VERIFY); } return TRUE; @@ -1736,8 +1994,7 @@ static void create_and_bind_fbo_attachment(const struct wined3d_gl_info *gl_info case WINED3D_GL_RES_TYPE_TEX_3D: gl_info->gl_ops.gl.p_glGenTextures(1, object); gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, *object); - GL_EXTCALL(glTexImage3D)(GL_TEXTURE_3D, 0, internal, 16, 16, 16, 0, - format, type, NULL); + GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, internal, 16, 16, 16, 0, format, type, NULL)); gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -2158,11 +2415,14 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for TRACE("Format %s's sRGB format is FBO attachable, type %u.\n", debug_d3dformat(format->id), type); format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + format->glInternal = format->glGammaInternal; } else { WARN("Format %s's sRGB format is not FBO attachable, type %u.\n", debug_d3dformat(format->id), type); + format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); } } else if (status == GL_FRAMEBUFFER_COMPLETE) @@ -2175,7 +2435,7 @@ static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_for } delete_fbo_attachment(gl_info, type, object); - checkGLcall("Framebuffer format check cleaup"); + checkGLcall("Framebuffer format check cleanup"); } if (fallback_fmt_used && regular_fmt_used) @@ -2299,11 +2559,14 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) TRACE("Format %s's sRGB format is FBO attachable, resource type %u.\n", debug_d3dformat(format->id), type); format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB; + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + format->glInternal = format->glGammaInternal; } else { WARN("Format %s's sRGB format is not FBO attachable, resource type %u.\n", debug_d3dformat(format->id), type); + format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE); } } else if (format->flags[type] & WINED3DFMT_FLAG_FBO_ATTACHABLE) @@ -2357,6 +2620,137 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); } +static GLenum lookup_gl_view_class(GLenum internal_format) +{ + static const struct + { + GLenum internal_format; + GLenum view_class; + } + view_classes[] = + { + /* 128-bit */ + {GL_RGBA32F, GL_VIEW_CLASS_128_BITS}, + {GL_RGBA32UI, GL_VIEW_CLASS_128_BITS}, + {GL_RGBA32I, GL_VIEW_CLASS_128_BITS}, + /* 96-bit */ + {GL_RGB32F, GL_VIEW_CLASS_96_BITS}, + {GL_RGB32UI, GL_VIEW_CLASS_96_BITS}, + {GL_RGB32I, GL_VIEW_CLASS_96_BITS}, + /* 64-bit */ + {GL_RGBA16F, GL_VIEW_CLASS_64_BITS}, + {GL_RG32F, GL_VIEW_CLASS_64_BITS}, + {GL_RGBA16UI, GL_VIEW_CLASS_64_BITS}, + {GL_RG32UI, GL_VIEW_CLASS_64_BITS}, + {GL_RGBA16I, GL_VIEW_CLASS_64_BITS}, + {GL_RG32I, GL_VIEW_CLASS_64_BITS}, + {GL_RGBA16, GL_VIEW_CLASS_64_BITS}, + {GL_RGBA16_SNORM, GL_VIEW_CLASS_64_BITS}, + /* 48-bit */ + {GL_RGB16, GL_VIEW_CLASS_48_BITS}, + {GL_RGB16_SNORM, GL_VIEW_CLASS_48_BITS}, + {GL_RGB16F, GL_VIEW_CLASS_48_BITS}, + {GL_RGB16UI, GL_VIEW_CLASS_48_BITS}, + {GL_RGB16I, GL_VIEW_CLASS_48_BITS}, + /* 32-bit */ + {GL_RG16F, GL_VIEW_CLASS_32_BITS}, + {GL_R11F_G11F_B10F, GL_VIEW_CLASS_32_BITS}, + {GL_R32F, GL_VIEW_CLASS_32_BITS}, + {GL_RGB10_A2UI, GL_VIEW_CLASS_32_BITS}, + {GL_RGBA8UI, GL_VIEW_CLASS_32_BITS}, + {GL_RG16UI, GL_VIEW_CLASS_32_BITS}, + {GL_R32UI, GL_VIEW_CLASS_32_BITS}, + {GL_RGBA8I, GL_VIEW_CLASS_32_BITS}, + {GL_RG16I, GL_VIEW_CLASS_32_BITS}, + {GL_R32I, GL_VIEW_CLASS_32_BITS}, + {GL_RGB10_A2, GL_VIEW_CLASS_32_BITS}, + {GL_RGBA8, GL_VIEW_CLASS_32_BITS}, + {GL_RG16, GL_VIEW_CLASS_32_BITS}, + {GL_RGBA8_SNORM, GL_VIEW_CLASS_32_BITS}, + {GL_RG16_SNORM, GL_VIEW_CLASS_32_BITS}, + {GL_SRGB8_ALPHA8, GL_VIEW_CLASS_32_BITS}, + {GL_RGB9_E5, GL_VIEW_CLASS_32_BITS}, + /* 24-bit */ + {GL_RGB8, GL_VIEW_CLASS_24_BITS}, + {GL_RGB8_SNORM, GL_VIEW_CLASS_24_BITS}, + {GL_SRGB8, GL_VIEW_CLASS_24_BITS}, + {GL_RGB8UI, GL_VIEW_CLASS_24_BITS}, + {GL_RGB8I, GL_VIEW_CLASS_24_BITS}, + /* 16-bit */ + {GL_R16F, GL_VIEW_CLASS_16_BITS}, + {GL_RG8UI, GL_VIEW_CLASS_16_BITS}, + {GL_R16UI, GL_VIEW_CLASS_16_BITS}, + {GL_RG8I, GL_VIEW_CLASS_16_BITS}, + {GL_R16I, GL_VIEW_CLASS_16_BITS}, + {GL_RG8, GL_VIEW_CLASS_16_BITS}, + {GL_R16, GL_VIEW_CLASS_16_BITS}, + {GL_RG8_SNORM, GL_VIEW_CLASS_16_BITS}, + {GL_R16_SNORM, GL_VIEW_CLASS_16_BITS}, + /* 8-bit */ + {GL_R8UI, GL_VIEW_CLASS_8_BITS}, + {GL_R8I, GL_VIEW_CLASS_8_BITS}, + {GL_R8, GL_VIEW_CLASS_8_BITS}, + {GL_R8_SNORM, GL_VIEW_CLASS_8_BITS}, + + /* RGTC1 */ + {GL_COMPRESSED_RED_RGTC1, GL_VIEW_CLASS_RGTC1_RED}, + {GL_COMPRESSED_SIGNED_RED_RGTC1, GL_VIEW_CLASS_RGTC1_RED}, + /* RGTC2 */ + {GL_COMPRESSED_RG_RGTC2, GL_VIEW_CLASS_RGTC2_RG}, + {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_VIEW_CLASS_RGTC2_RG}, + + /* BPTC unorm */ + {GL_COMPRESSED_RGBA_BPTC_UNORM, GL_VIEW_CLASS_BPTC_UNORM}, + {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_VIEW_CLASS_BPTC_UNORM}, + /* BPTC float */ + {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_VIEW_CLASS_BPTC_FLOAT}, + {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_VIEW_CLASS_BPTC_FLOAT}, + + /* DXT1 RGB */ + {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGB}, + {GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGB}, + /* DXT1 RGBA */ + {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGBA}, + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_VIEW_CLASS_S3TC_DXT1_RGBA}, + /* DXT3 */ + {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_VIEW_CLASS_S3TC_DXT3_RGBA}, + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_VIEW_CLASS_S3TC_DXT3_RGBA}, + /* DXT5 */ + {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_VIEW_CLASS_S3TC_DXT5_RGBA}, + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_VIEW_CLASS_S3TC_DXT5_RGBA}, + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(view_classes); ++i) + { + if (view_classes[i].internal_format == internal_format) + return view_classes[i].view_class; + } + + return GL_NONE; +} + +static void query_view_class(struct wined3d_format *format) +{ + GLenum internal_view_class, gamma_view_class, rt_view_class; + + internal_view_class = lookup_gl_view_class(format->glInternal); + gamma_view_class = lookup_gl_view_class(format->glGammaInternal); + rt_view_class = lookup_gl_view_class(format->rtInternal); + + if (internal_view_class == gamma_view_class || gamma_view_class == rt_view_class) + { + format->gl_view_class = internal_view_class; + TRACE("Format %s is member of GL view class %#x.\n", + debug_d3dformat(format->id), format->gl_view_class); + } + else + { + format->gl_view_class = GL_NONE; + } +} + static void query_internal_format(struct wined3d_adapter *adapter, struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info, struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format) @@ -2384,13 +2778,14 @@ static void query_internal_format(struct wined3d_adapter *adapter, if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) format->glGammaInternal = format->glInternal; - else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) format->glInternal = format->glGammaInternal; } } else { - if (!gl_info->limits.vertex_samplers) + if (!gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]) format_clear_flag(format, WINED3DFMT_FLAG_VTF); if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) @@ -2406,7 +2801,8 @@ static void query_internal_format(struct wined3d_adapter *adapter, format->glGammaInternal = format->glInternal; format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); } - else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) { format->glInternal = format->glGammaInternal; } @@ -2426,11 +2822,14 @@ static void query_internal_format(struct wined3d_adapter *adapter, } } + query_view_class(format); + if (format->glInternal && format->flags[WINED3D_GL_RES_TYPE_RB] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) { if (gl_info->supported[ARB_INTERNALFORMAT_QUERY]) { + count = 0; GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, GL_NUM_SAMPLE_COUNTS, 1, &count)); checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)"); @@ -2447,16 +2846,23 @@ static void query_internal_format(struct wined3d_adapter *adapter, } else { - max_log2 = wined3d_log2i(min(gl_info->limits.samples, - sizeof(format->multisample_types) * 8)); - for (i = 1; i <= max_log2; ++i) - format->multisample_types |= 1u << ((1u << i) - 1); +#ifdef __REACTOS__ + if (gl_info->limits.samples) { +#endif + max_log2 = wined3d_log2i(min(gl_info->limits.samples, + sizeof(format->multisample_types) * 8)); + for (i = 1; i <= max_log2; ++i) + format->multisample_types |= 1u << ((1u << i) - 1); +#ifdef __REACTOS__ + } +#endif } } } static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) { + struct wined3d_format *format, *srgb_format; struct fragment_caps fragment_caps; struct shader_caps shader_caps; unsigned int i, j; @@ -2467,21 +2873,13 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE) && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE); - for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i) + for (i = 0; i < ARRAY_SIZE(format_texture_info); ++i) { - int srgb_fmt_idx = -1, fmt_idx = get_format_idx(format_texture_info[i].id); - struct wined3d_format *format, *srgb_format; - - if (fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id); + if (!(format = get_format_internal(gl_info, format_texture_info[i].id))) return FALSE; - } - if (!gl_info->supported[format_texture_info[i].extension]) continue; - - format = &gl_info->formats[fmt_idx]; + if (!gl_info->supported[format_texture_info[i].extension]) + continue; /* ARB_texture_rg defines floating point formats, but only if * ARB_texture_float is also supported. */ @@ -2535,29 +2933,20 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win format->convert = format_texture_info[i].convert; format->conv_byte_count = format_texture_info[i].conv_byte_count; - for (j = 0; j < sizeof(format_srgb_info) / sizeof(*format_srgb_info); ++j) + srgb_format = NULL; + for (j = 0; j < ARRAY_SIZE(format_srgb_info); ++j) { if (format_srgb_info[j].base_format_id == format->id) { - srgb_fmt_idx = get_format_idx(format_srgb_info[j].srgb_format_id); - if (srgb_fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(format_srgb_info[j].srgb_format_id), - format_srgb_info[j].srgb_format_id); + if (!(srgb_format = get_format_internal(gl_info, format_srgb_info[j].srgb_format_id))) return FALSE; - } break; } } - - if (srgb_fmt_idx == -1) + if (!srgb_format) continue; - srgb_format = &gl_info->formats[srgb_fmt_idx]; - - *srgb_format = *format; - srgb_format->id = format_srgb_info[j].srgb_format_id; + copy_format(srgb_format, format); if (gl_info->supported[EXT_TEXTURE_SRGB] && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) @@ -2673,6 +3062,7 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex); gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); if (gl_info->gl_ops.gl.p_glGetError()) { @@ -2853,11 +3243,30 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { + idx = get_format_idx(WINED3DFMT_A8_UNORM); + gl_info->formats[idx].color_fixup = create_color_fixup_desc( + 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_X); + idx = get_format_idx(WINED3DFMT_L8A8_UNORM); + gl_info->formats[idx].color_fixup = create_color_fixup_desc( + 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); + idx = get_format_idx(WINED3DFMT_L4A4_UNORM); + gl_info->formats[idx].color_fixup = create_color_fixup_desc( + 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y); + idx = get_format_idx(WINED3DFMT_L16_UNORM); + gl_info->formats[idx].color_fixup = create_color_fixup_desc( + 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); idx = get_format_idx(WINED3DFMT_INTZ); gl_info->formats[idx].color_fixup = create_color_fixup_desc( 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X); } + if (gl_info->supported[ARB_TEXTURE_RG]) + { + idx = get_format_idx(WINED3DFMT_L8_UNORM); + gl_info->formats[idx].color_fixup = create_color_fixup_desc( + 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE); + } + if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { idx = get_format_idx(WINED3DFMT_P8_UINT); @@ -2870,15 +3279,15 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ gl_info->formats[idx].gl_vtx_format = GL_BGRA; } - if (gl_info->supported[ARB_HALF_FLOAT_VERTEX]) + if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) { /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though. * It is the job of the vertex buffer code to make sure that the vbos have the right format */ idx = get_format_idx(WINED3DFMT_R16G16_FLOAT); - gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */ + gl_info->formats[idx].gl_vtx_type = GL_FLOAT; idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT); - gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; + gl_info->formats[idx].gl_vtx_type = GL_FLOAT; } if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) @@ -2948,7 +3357,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup) || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup)) - format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE); + format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE); } /* GL_EXT_texture_compression_s3tc does not support 3D textures. Some Windows drivers @@ -2968,40 +3377,82 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; idx = get_format_idx(WINED3DFMT_BC1_UNORM); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; idx = get_format_idx(WINED3DFMT_BC2_UNORM); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC2_UNORM_SRGB); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; idx = get_format_idx(WINED3DFMT_BC3_UNORM); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC3_UNORM_SRGB); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; /* Similarly with ATI1N / ATI2N and GL_ARB_texture_compression_rgtc. */ idx = get_format_idx(WINED3DFMT_ATI1N); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; idx = get_format_idx(WINED3DFMT_ATI2N); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC4_UNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC5_UNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = get_format_idx(WINED3DFMT_BC5_SNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; +} + +static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int component_count) +{ + switch (type) + { + case GL_HALF_FLOAT: + return component_count * sizeof(GLhalfNV); + case GL_FLOAT: + return component_count * sizeof(GLfloat); + case GL_BYTE: + return component_count * sizeof(GLbyte); + case GL_UNSIGNED_BYTE: + return component_count * sizeof(GLubyte); + case GL_SHORT: + return component_count * sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return component_count * sizeof(GLushort); + case GL_INT: + return component_count * sizeof(GLint); + case GL_UNSIGNED_INT: + return component_count * sizeof(GLuint); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return sizeof(GLuint); + default: + FIXME("Unhandled GL type %#x.\n", type); + return 0; + } } static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) { + struct wined3d_format *format; unsigned int i; - for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i) + for (i = 0; i < ARRAY_SIZE(format_vertex_info); ++i) { - struct wined3d_format *format; - int fmt_idx = get_format_idx(format_vertex_info[i].id); - - if (fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id); + if (!(format = get_format_internal(gl_info, format_vertex_info[i].id))) return FALSE; - } - format = &gl_info->formats[fmt_idx]; + if (!gl_info->supported[format_vertex_info[i].extension]) + continue; + format->emit_idx = format_vertex_info[i].emit_idx; format->component_count = format_vertex_info[i].component_count; format->gl_vtx_type = format_vertex_info[i].gl_vtx_type; - format->gl_vtx_format = format_vertex_info[i].gl_vtx_format; + format->gl_vtx_format = format_vertex_info[i].component_count; format->gl_normalized = format_vertex_info[i].gl_normalized; - format->component_size = format_vertex_info[i].component_size; + if (!(format->attribute_size = calculate_vertex_attribute_size(format->gl_vtx_type, + format->component_count))) + { + ERR("Invalid attribute size for vertex format %s (%#x).\n", + debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id); + return FALSE; + } } return TRUE; @@ -3015,46 +3466,50 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) { struct wined3d_format *format, *typeless_format; - int fmt_idx = get_format_idx(typed_formats[i].id); - int typeless_fmt_idx = get_format_idx(typed_formats[i].typeless_id); - if (fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(typed_formats[i].id), - typed_formats[i].id); + if (!(format = get_format_internal(gl_info, typed_formats[i].id))) return FALSE; - } - if (typeless_fmt_idx == -1) - { - ERR("Format %s (%#x) not found.\n", - debug_d3dformat(typed_formats[i].typeless_id), - typed_formats[i].typeless_id); + if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id))) return FALSE; - } - - format = &gl_info->formats[fmt_idx]; - typeless_format = &gl_info->formats[typeless_fmt_idx]; memcpy(flags, typeless_format->flags, sizeof(flags)); - *typeless_format = *format; - typeless_format->id = typed_formats[i].typeless_id; + copy_format(typeless_format, format); for (j = 0; j < ARRAY_SIZE(typeless_format->flags); ++j) typeless_format->flags[j] |= flags[j]; } - return TRUE; -} - -BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) -{ - if (!init_format_base_info(gl_info)) return FALSE; - - if (!init_format_block_info(gl_info)) + for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) { - HeapFree(GetProcessHeap(), 0, gl_info->formats); - gl_info->formats = NULL; - return FALSE; + struct wined3d_format *typeless_format, *typeless_ds_format, *ds_format; + struct wined3d_format *depth_view_format, *stencil_view_format; + enum wined3d_format_id format_id; + + if (!(typeless_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].typeless_id))) + return FALSE; + if (!(ds_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].depth_stencil_id))) + return FALSE; + + typeless_ds_format = &gl_info->formats[WINED3D_FORMAT_COUNT + i]; + typeless_ds_format->id = typeless_depth_stencil_formats[i].typeless_id; + copy_format(typeless_ds_format, ds_format); + for (j = 0; j < ARRAY_SIZE(typeless_ds_format->flags); ++j) + { + typeless_ds_format->flags[j] = typeless_format->flags[j]; + typeless_format->flags[j] &= ~(WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); + } + + if ((format_id = typeless_depth_stencil_formats[i].depth_view_id)) + { + if (!(depth_view_format = get_format_internal(gl_info, format_id))) + return FALSE; + copy_format(depth_view_format, ds_format); + } + if ((format_id = typeless_depth_stencil_formats[i].stencil_view_id)) + { + if (!(stencil_view_format = get_format_internal(gl_info, format_id))) + return FALSE; + copy_format(stencil_view_format, ds_format); + } } return TRUE; @@ -3066,8 +3521,11 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi struct wined3d_gl_info *gl_info = &adapter->gl_info; if (!init_format_base_info(gl_info)) return FALSE; - if (!init_format_block_info(gl_info)) goto fail; + + if (!ctx) /* WINED3D_NO3D */ + return TRUE; + if (!init_format_texture_info(adapter, gl_info)) goto fail; if (!init_format_vertex_info(gl_info)) goto fail; @@ -3084,6 +3542,53 @@ fail: return FALSE; } +BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) +{ + static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f}; + const struct wined3d_gl_info *gl_info = ctx->gl_info; + static const float offset = -63.0f / 128.0f; + GLuint texture, fbo; + DWORD readback[4]; + unsigned int i; + + gl_info->gl_ops.gl.p_glGenTextures(1, &texture); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); + gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ARRAY_SIZE(readback), 1, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, texture, 0); + checkGLcall("create resources"); + + gl_info->gl_ops.gl.p_glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT); + GL_EXTCALL(glViewportIndexedf(0, offset, offset, 4.0f, 1.0f)); + draw_test_quad(ctx, NULL, &red); + checkGLcall("draw"); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture); + gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback); + checkGLcall("readback"); + + TRACE("Readback colors are 0x%08x, 0x%08x, 0x%08x, 0x%08x.\n", + readback[0], readback[1], readback[2], readback[3]); + + gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture); + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + checkGLcall("delete resources"); + + for (i = 0; i < ARRAY_SIZE(readback); ++i) + { + if (readback[i] != 0xffff0000) + return FALSE; + } + return TRUE; +} + float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *ctx, GLenum format) { const struct wined3d_gl_info *gl_info = ctx->gl_info; @@ -3179,63 +3684,37 @@ float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *ctx, GLe } const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, - enum wined3d_format_id format_id) + enum wined3d_format_id format_id, unsigned int resource_usage) { + const struct wined3d_format *format; int idx = get_format_idx(format_id); + unsigned int i; if (idx == -1) { - FIXME("Can't find format %s (%#x) in the format lookup table\n", + FIXME("Can't find format %s (%#x) in the format lookup table.\n", debug_d3dformat(format_id), format_id); - /* Get the caller a valid pointer */ - idx = get_format_idx(WINED3DFMT_UNKNOWN); + return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; } - return &gl_info->formats[idx]; + format = &gl_info->formats[idx]; + + if (resource_usage & WINED3DUSAGE_DEPTHSTENCIL && wined3d_format_is_typeless(format)) + { + for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i) + { + if (typeless_depth_stencil_formats[i].typeless_id == format_id) + return &gl_info->formats[WINED3D_FORMAT_COUNT + i]; + } + + FIXME("Cannot find depth/stencil typeless format %s (%#x).\n", + debug_d3dformat(format_id), format_id); + return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)]; + } + + return format; } -#if defined(STAGING_CSMT) -UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width) -{ - /* For block based formats, pitch means the amount of bytes to the next - * row of blocks rather than the next row of pixels. */ - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) - return format->block_byte_count * ((width + format->block_width - 1) / format->block_width); - - return format->byte_count * width; -} - -UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, - UINT width, UINT height, UINT depth) -{ - UINT pitch = wined3d_format_calculate_pitch(format, width); - UINT size; - - if (format->id == WINED3DFMT_UNKNOWN) - { - size = 0; - } - else if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) - { - UINT row_count = (height + format->block_height - 1) / format->block_height; - size = row_count * ((pitch + alignment - 1) & ~(alignment - 1)); - } - else - { - size = height * ((pitch + alignment - 1) & ~(alignment - 1)); - } - - if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) - { - /* The D3D format requirements make sure that the resulting format is an integer again */ - size *= format->height_scale.numerator; - size /= format->height_scale.denominator; - } - - size *= depth; - - return size; -#else /* STAGING_CSMT */ void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) { @@ -3274,10 +3753,12 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT ali if (format->id == WINED3DFMT_UNKNOWN) return 0; + if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BROKEN_PITCH) + return width * height * depth * format->byte_count; + wined3d_format_calculate_pitch(format, alignment, width, height, &row_pitch, &slice_pitch); return slice_pitch * depth; -#endif /* STAGING_CSMT */ } /***************************************************************************** @@ -3292,6 +3773,38 @@ const char *debug_box(const struct wined3d_box *box) box->right, box->bottom, box->back); } +const char *debug_color(const struct wined3d_color *color) +{ + if (!color) + return "(null)"; + return wine_dbg_sprintf("{%.8e, %.8e, %.8e, %.8e}", + color->r, color->g, color->b, color->a); +} + +const char *debug_ivec4(const struct wined3d_ivec4 *v) +{ + if (!v) + return "(null)"; + return wine_dbg_sprintf("{%d, %d, %d, %d}", + v->x, v->y, v->z, v->w); +} + +const char *debug_uvec4(const struct wined3d_uvec4 *v) +{ + if (!v) + return "(null)"; + return wine_dbg_sprintf("{%u, %u, %u, %u}", + v->x, v->y, v->z, v->w); +} + +const char *debug_vec4(const struct wined3d_vec4 *v) +{ + if (!v) + return "(null)"; + return wine_dbg_sprintf("{%.8e, %.8e, %.8e, %.8e}", + v->x, v->y, v->z, v->w); +} + const char *debug_d3dformat(enum wined3d_format_id format_id) { switch (format_id) @@ -3314,6 +3827,8 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM); FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM); FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM); + FMT_TO_STR(WINED3DFMT_R10G10B10X2_UINT); + FMT_TO_STR(WINED3DFMT_R10G10B10X2_SNORM); FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM); FMT_TO_STR(WINED3DFMT_UYVY); FMT_TO_STR(WINED3DFMT_YUY2); @@ -3334,7 +3849,6 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM); FMT_TO_STR(WINED3DFMT_L16_UNORM); FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT); - FMT_TO_STR(WINED3DFMT_VERTEXDATA); FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx); FMT_TO_STR(WINED3DFMT_ATI1N); FMT_TO_STR(WINED3DFMT_ATI2N); @@ -3367,6 +3881,7 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM); FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT); FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM); + FMT_TO_STR(WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM); FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT); FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS); FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM); @@ -3434,6 +3949,9 @@ const char *debug_d3dformat(enum wined3d_format_id format_id) FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM_SRGB); FMT_TO_STR(WINED3DFMT_B8G8R8X8_TYPELESS); FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM_SRGB); + FMT_TO_STR(WINED3DFMT_BC6H_TYPELESS); + FMT_TO_STR(WINED3DFMT_BC6H_UF16); + FMT_TO_STR(WINED3DFMT_BC6H_SF16); FMT_TO_STR(WINED3DFMT_BC7_TYPELESS); FMT_TO_STR(WINED3DFMT_BC7_UNORM); FMT_TO_STR(WINED3DFMT_BC7_UNORM_SRGB); @@ -3477,7 +3995,7 @@ const char *debug_d3ddevicetype(enum wined3d_device_type device_type) const char *debug_d3dusage(DWORD usage) { - char buf[333]; + char buf[552]; buf[0] = '\0'; #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; } @@ -3491,7 +4009,14 @@ const char *debug_d3dusage(DWORD usage) WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES); WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC); WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE); WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTAPI); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_LEGACY_CUBEMAP); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_TEXTURE); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_OWNDC); WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL); WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY); #undef WINED3DUSAGE_TO_STR @@ -3583,9 +4108,8 @@ const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type) switch (resource_type) { #define WINED3D_TO_STR(x) case x: return #x - WINED3D_TO_STR(WINED3D_RTYPE_SURFACE); - WINED3D_TO_STR(WINED3D_RTYPE_VOLUME); WINED3D_TO_STR(WINED3D_RTYPE_BUFFER); + WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D); WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D); WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D); #undef WINED3D_TO_STR @@ -3611,9 +4135,10 @@ const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type) PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ); PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ); PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ); + PRIM_TO_STR(WINED3D_PT_PATCH); #undef PRIM_TO_STR default: - FIXME("Unrecognized %u primitive type!\n", primitive_type); + FIXME("Unrecognized primitive type %#x.\n", primitive_type); return "unrecognized"; } } @@ -3727,10 +4252,10 @@ const char *debug_d3drenderstate(enum wined3d_render_state state) D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W); D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION); D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE); - D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL); - D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL); - D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS); - D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFAIL); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS); + D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2); D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3); @@ -3796,7 +4321,7 @@ const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_t D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD); #undef D3DTEXTUREFILTERTYPE_TO_STR default: - FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type); + FIXME("Unrecognized texture filter type 0x%08x.\n", filter_type); return "unrecognized"; } } @@ -3900,7 +4425,7 @@ const char *debug_d3dtstype(enum wined3d_transform_state tstype) } } -static const char *debug_shader_type(enum wined3d_shader_type type) +const char *debug_shader_type(enum wined3d_shader_type type) { switch(type) { @@ -3908,6 +4433,9 @@ static const char *debug_shader_type(enum wined3d_shader_type type) WINED3D_TO_STR(WINED3D_SHADER_TYPE_PIXEL); WINED3D_TO_STR(WINED3D_SHADER_TYPE_VERTEX); WINED3D_TO_STR(WINED3D_SHADER_TYPE_GEOMETRY); + WINED3D_TO_STR(WINED3D_SHADER_TYPE_HULL); + WINED3D_TO_STR(WINED3D_SHADER_TYPE_DOMAIN); + WINED3D_TO_STR(WINED3D_SHADER_TYPE_COMPUTE); #undef WINED3D_TO_STR default: FIXME("Unrecognized shader type %#x.\n", type); @@ -3928,12 +4456,22 @@ const char *debug_d3dstate(DWORD state) } if (STATE_IS_SAMPLER(state)) return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0)); - if (STATE_IS_SHADER(state)) + if (STATE_IS_COMPUTE_SHADER(state)) + return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(WINED3D_SHADER_TYPE_COMPUTE)); + if (STATE_IS_GRAPHICS_SHADER(state)) return wine_dbg_sprintf("STATE_SHADER(%s)", debug_shader_type(state - STATE_SHADER(0))); - if (STATE_IS_CONSTANT_BUFFER(state)) + if (STATE_IS_COMPUTE_CONSTANT_BUFFER(state)) + return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(WINED3D_SHADER_TYPE_COMPUTE)); + if (STATE_IS_GRAPHICS_CONSTANT_BUFFER(state)) return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0))); - if (STATE_IS_SHADER_RESOURCE_BINDING(state)) - return "STATE_SHADER_RESOURCE_BINDING"; + if (STATE_IS_COMPUTE_SHADER_RESOURCE_BINDING(state)) + return "STATE_COMPUTE_SHADER_RESOURCE_BINDING"; + if (STATE_IS_GRAPHICS_SHADER_RESOURCE_BINDING(state)) + return "STATE_GRAPHICS_SHADER_RESOURCE_BINDING"; + if (STATE_IS_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING(state)) + return "STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING"; + if (STATE_IS_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING(state)) + return "STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING"; if (STATE_IS_TRANSFORM(state)) return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0))); if (STATE_IS_STREAMSRC(state)) @@ -3966,6 +4504,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_POINT_ENABLE"; if (STATE_IS_COLOR_KEY(state)) return "STATE_COLOR_KEY"; + if (STATE_IS_STREAM_OUTPUT(state)) + return "STATE_STREAM_OUTPUT"; return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } @@ -3986,6 +4526,35 @@ const char *debug_d3dpool(enum wined3d_pool pool) } } +const char *debug_fboattachment(GLenum attachment) +{ + switch(attachment) + { +#define WINED3D_TO_STR(x) case x: return #x + WINED3D_TO_STR(GL_COLOR_ATTACHMENT0); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT1); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT2); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT3); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT4); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT5); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT6); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT7); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT8); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT9); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT10); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT11); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT12); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT13); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT14); + WINED3D_TO_STR(GL_COLOR_ATTACHMENT15); + WINED3D_TO_STR(GL_DEPTH_ATTACHMENT); + WINED3D_TO_STR(GL_STENCIL_ATTACHMENT); +#undef WINED3D_TO_STR + default: + return wine_dbg_sprintf("Unknown FBO attachment %#x", attachment); + } +} + const char *debug_fbostatus(GLenum status) { switch(status) { #define FBOSTATUS_TO_STR(u) case u: return #u @@ -3997,11 +4566,13 @@ const char *debug_fbostatus(GLenum status) { FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED); #undef FBOSTATUS_TO_STR default: - FIXME("Unrecognied FBO status 0x%08x\n", status); + FIXME("Unrecognized FBO status 0x%08x.\n", status); return "unrecognized"; } } @@ -4019,7 +4590,7 @@ const char *debug_glerror(GLenum error) { GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION); #undef GLERROR_TO_STR default: - FIXME("Unrecognied GL error 0x%08x\n", error); + FIXME("Unrecognized GL error 0x%08x.\n", error); return "unrecognized"; } } @@ -4121,14 +4692,16 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_matrix *mat) { + BOOL clip_control = context->gl_info->supported[ARB_CLIP_CONTROL]; + BOOL flip = !clip_control && context->render_offscreen; float center_offset; /* There are a couple of additional things we have to take into account * here besides the projection transformation itself: * - We need to flip along the y-axis in case of offscreen rendering. * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}. - * - D3D coordinates refer to pixel centers while GL coordinates refer - * to pixel corners. + * - <= D3D9 coordinates refer to pixel centers while GL coordinates + * refer to pixel corners. * - D3D has a top-left filling convention. We need to maintain this * even after the y-flip mentioned above. * In order to handle the last two points, we translate by @@ -4138,7 +4711,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * driver, but small enough to prevent it from interfering with any * anti-aliasing. */ - if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (!clip_control && context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; @@ -4152,18 +4725,14 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w float h = state->viewport.height; float x_scale = 2.0f / w; float x_offset = (center_offset - (2.0f * x) - w) / w; - float y_scale = context->render_offscreen ? 2.0f / h : 2.0f / -h; - float y_offset = context->render_offscreen + float y_scale = flip ? 2.0f / h : 2.0f / -h; + float y_offset = flip ? (center_offset - (2.0f * y) - h) / h : (center_offset - (2.0f * y) - h) / -h; -#if defined(STAGING_CSMT) - enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? -#else /* STAGING_CSMT */ enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? -#endif /* STAGING_CSMT */ state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; - float z_scale = zenable ? 2.0f : 0.0f; - float z_offset = zenable ? -1.0f : 0.0f; + float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; + float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; const struct wined3d_matrix projection = { x_scale, 0.0f, 0.0f, 0.0f, @@ -4176,17 +4745,19 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w } else { - float y_scale = context->render_offscreen ? -1.0f : 1.0f; + float y_scale = flip ? -1.0f : 1.0f; float x_offset = center_offset / state->viewport.width; - float y_offset = context->render_offscreen + float y_offset = flip ? center_offset / state->viewport.height : -center_offset / state->viewport.height; + float z_scale = clip_control ? 1.0f : 2.0f; + float z_offset = clip_control ? 0.0f : -1.0f; const struct wined3d_matrix projection = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, y_scale, 0.0f, 0.0f, - 0.0f, 0.0f, 2.0f, 0.0f, - x_offset, y_offset, -1.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, y_scale, 0.0f, 0.0f, + 0.0f, 0.0f, z_scale, 0.0f, + x_offset, y_offset, z_offset, 1.0f, }; multiply_matrix(mat, &projection, &state->transforms[WINED3D_TS_PROJECTION]); @@ -4283,33 +4854,20 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ case WINED3D_TTFF_COUNT2: mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; -#if defined(STAGING_CSMT) - /* OpenGL divides the first 3 vertex coord by the 4th by default, - * which is essentially the same as D3DTTFF_PROJECTED. Make sure that - * the 4th coord evaluates to 1.0 to eliminate that. - * - * If the fixed function pipeline is used, the 4th value remains unused, - * so there is no danger in doing this. With vertex shaders we have a - * problem. Should an app hit that problem, the code here would have to - * check for pixel shaders, and the shader has to undo the default gl divide. - * - * A more serious problem occurs if the app passes 4 coordinates in, and the - * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow - * or a replacement shader. */ -#else /* STAGING_CSMT */ - /* OpenGL divides the first 3 vertex coord by the 4th by default, - * which is essentially the same as D3DTTFF_PROJECTED. Make sure that - * the 4th coord evaluates to 1.0 to eliminate that. - * - * If the fixed function pipeline is used, the 4th value remains unused, - * so there is no danger in doing this. With vertex shaders we have a - * problem. Should an app hit that problem, the code here would have to - * check for pixel shaders, and the shader has to undo the default gl divide. - * - * A more serious problem occurs if the app passes 4 coordinates in, and the - * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow - * or a replacement shader. */ -#endif /* STAGING_CSMT */ + /* OpenGL divides the first 3 vertex coordinates by the 4th by + * default, which is essentially the same as D3DTTFF_PROJECTED. + * Make sure that the 4th coordinate evaluates to 1.0 to + * eliminate that. + * + * If the fixed function pipeline is used, the 4th value + * remains unused, so there is no danger in doing this. With + * vertex shaders we have a problem. Should an application hit + * that problem, the code here would have to check for pixel + * shaders, and the shader has to undo the default GL divide. + * + * A more serious problem occurs if the application passes 4 + * coordinates in, and the 4th is != 1.0 (OpenGL default). + * This would have to be fixed with immediate mode draws. */ default: mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; } @@ -4322,7 +4880,7 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int tex, struct wined3d_matrix *mat) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; const struct wined3d_gl_info *gl_info = context->gl_info; BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; @@ -4450,55 +5008,76 @@ void get_fog_start_end(const struct wined3d_context *context, const struct wined /* 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. */ -DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color) +DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color) { static const struct { enum wined3d_format_id format_id; - float r_mul; - float g_mul; - float b_mul; - float a_mul; - BYTE r_shift; - BYTE g_shift; - BYTE b_shift; - BYTE a_shift; + struct wined3d_vec4 mul; + struct wined3d_uvec4 shift; } - conv[] = + float_conv[] = { - {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, - {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, - {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24}, - {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0}, - {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15}, - {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15}, - {WINED3DFMT_R8_UNORM, 255.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0}, - {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0}, - {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12}, - {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12}, - {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0}, - {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24}, - {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24}, - {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30}, - {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30}, - {WINED3DFMT_P8_UINT, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0}, + {WINED3DFMT_B8G8R8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, + {WINED3DFMT_B8G8R8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, + {WINED3DFMT_B8G8R8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, + {WINED3DFMT_B5G6R5_UNORM, { 31.0f, 63.0f, 31.0f, 0.0f}, {11, 5, 0, 0}}, + {WINED3DFMT_B5G5R5A1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, + {WINED3DFMT_B5G5R5X1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, + {WINED3DFMT_R8_UNORM, { 255.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, + {WINED3DFMT_A8_UNORM, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, + {WINED3DFMT_B4G4R4A4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, + {WINED3DFMT_B4G4R4X4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, + {WINED3DFMT_B2G3R3_UNORM, { 7.0f, 7.0f, 3.0f, 0.0f}, { 5, 2, 0, 0}}, + {WINED3DFMT_R8G8B8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, + {WINED3DFMT_R8G8B8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, + {WINED3DFMT_B10G10R10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, {20, 10, 0, 30}}, + {WINED3DFMT_R10G10B10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, { 0, 10, 20, 30}}, + {WINED3DFMT_P8_UINT, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, + {WINED3DFMT_S1_UINT_D15_UNORM, { 32767.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, + {WINED3DFMT_D16_UNORM, { 65535.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, }; - const struct wined3d_format *format = surface->resource.format; - unsigned int i; - - TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n", - color->r, color->g, color->b, color->a, debug_d3dformat(format->id)); - - for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i) + static const struct { - DWORD ret; + enum wined3d_format_id format_id; + struct wined3d_dvec4 mul; + struct wined3d_uvec4 shift; + } + double_conv[] = + { + {WINED3DFMT_D24_UNORM_S8_UINT, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, + {WINED3DFMT_X8D24_UNORM, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, + {WINED3DFMT_D32_UNORM, {4294967295.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}}, + }; + unsigned int i; + DWORD ret; - if (format->id != conv[i].format_id) continue; + TRACE("Converting color %s to format %s.\n", debug_color(color), debug_d3dformat(format->id)); - ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift; - ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift; - ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift; - ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift; + for (i = 0; i < ARRAY_SIZE(float_conv); ++i) + { + if (format->id != float_conv[i].format_id) + continue; + + ret = ((DWORD)((color->r * float_conv[i].mul.x) + 0.5f)) << float_conv[i].shift.x; + ret |= ((DWORD)((color->g * float_conv[i].mul.y) + 0.5f)) << float_conv[i].shift.y; + ret |= ((DWORD)((color->b * float_conv[i].mul.z) + 0.5f)) << float_conv[i].shift.z; + ret |= ((DWORD)((color->a * float_conv[i].mul.w) + 0.5f)) << float_conv[i].shift.w; + + TRACE("Returning 0x%08x.\n", ret); + + return ret; + } + + for (i = 0; i < ARRAY_SIZE(double_conv); ++i) + { + if (format->id != double_conv[i].format_id) + continue; + + ret = ((DWORD)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x; + ret |= ((DWORD)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y; + ret |= ((DWORD)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z; + ret |= ((DWORD)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].shift.w; TRACE("Returning 0x%08x.\n", ret); @@ -4512,7 +5091,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c static float color_to_float(DWORD color, DWORD size, DWORD offset) { - DWORD mask = (1u << size) - 1; + DWORD mask = size < 32 ? (1u << size) - 1 : ~0u; if (!size) return 1.0f; @@ -4523,57 +5102,6 @@ static float color_to_float(DWORD color, DWORD size, DWORD offset) return (float)color / (float)mask; } -BOOL wined3d_format_convert_color_to_float(const struct wined3d_format *format, - const struct wined3d_palette *palette, DWORD color, struct wined3d_color *float_color) -{ - switch (format->id) - { - case WINED3DFMT_B8G8R8_UNORM: - case WINED3DFMT_B8G8R8A8_UNORM: - case WINED3DFMT_B8G8R8X8_UNORM: - case WINED3DFMT_B5G6R5_UNORM: - case WINED3DFMT_B5G5R5X1_UNORM: - case WINED3DFMT_B5G5R5A1_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - case WINED3DFMT_B2G3R3_UNORM: - case WINED3DFMT_R8_UNORM: - case WINED3DFMT_A8_UNORM: - case WINED3DFMT_B2G3R3A8_UNORM: - case WINED3DFMT_B4G4R4X4_UNORM: - case WINED3DFMT_R10G10B10A2_UNORM: - case WINED3DFMT_R10G10B10A2_SNORM: - case WINED3DFMT_R8G8B8A8_UNORM: - case WINED3DFMT_R8G8B8X8_UNORM: - case WINED3DFMT_R16G16_UNORM: - case WINED3DFMT_B10G10R10A2_UNORM: - float_color->r = color_to_float(color, format->red_size, format->red_offset); - float_color->g = color_to_float(color, format->green_size, format->green_offset); - float_color->b = color_to_float(color, format->blue_size, format->blue_offset); - float_color->a = color_to_float(color, format->alpha_size, format->alpha_offset); - return TRUE; - - case WINED3DFMT_P8_UINT: - if (palette) - { - float_color->r = palette->colors[color].rgbRed / 255.0f; - float_color->g = palette->colors[color].rgbGreen / 255.0f; - float_color->b = palette->colors[color].rgbBlue / 255.0f; - } - else - { - float_color->r = 0.0f; - float_color->g = 0.0f; - float_color->b = 0.0f; - } - float_color->a = color / 255.0f; - return TRUE; - - default: - ERR("Unhandled conversion from %s to floating point.\n", debug_d3dformat(format->id)); - return FALSE; - } -} - void wined3d_format_get_float_color_key(const struct wined3d_format *format, const struct wined3d_color_key *key, struct wined3d_color *float_colors) { @@ -4599,10 +5127,10 @@ void wined3d_format_get_float_color_key(const struct wined3d_format *format, case WINED3DFMT_R8G8B8X8_UNORM: case WINED3DFMT_R16G16_UNORM: case WINED3DFMT_B10G10R10A2_UNORM: - slop.r = 0.5f / ((1 << format->red_size) - 1); - slop.g = 0.5f / ((1 << format->green_size) - 1); - slop.b = 0.5f / ((1 << format->blue_size) - 1); - slop.a = 0.5f / ((1 << format->alpha_size) - 1); + slop.r = 0.5f / ((1u << format->red_size) - 1); + slop.g = 0.5f / ((1u << format->green_size) - 1); + slop.b = 0.5f / ((1u << format->blue_size) - 1); + slop.a = 0.5f / ((1u << format->alpha_size) - 1); float_colors[0].r = color_to_float(key->color_space_low_value, format->red_size, format->red_offset) - slop.r; @@ -4782,7 +5310,10 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d if ((texture = state->textures[i])) { - settings->op[i].color_fixup = texture->resource.format->color_fixup; + if (can_use_texture_swizzle(gl_info, texture->resource.format)) + settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY; + else + settings->op[i].color_fixup = texture->resource.format->color_fixup; if (ignore_textype) { settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; @@ -4969,11 +5500,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d break; } } -#if defined(STAGING_CSMT) - settings->sRGB_write = !gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, &state->fb); -#else /* STAGING_CSMT */ settings->sRGB_write = !gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb); -#endif /* STAGING_CSMT */ if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] || !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) { @@ -5030,6 +5557,13 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->gl_primitive_type == GL_POINTS; + if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + settings->alpha_test_func = WINED3D_CMP_ALWAYS - 1; + else + settings->alpha_test_func = (state->render_states[WINED3D_RS_ALPHATESTENABLE] + ? wined3d_sanitize_cmp_func(state->render_states[WINED3D_RS_ALPHAFUNC]) + : WINED3D_CMP_ALWAYS) - 1; + if (d3d_info->emulated_flatshading) settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; else @@ -5063,7 +5597,27 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st { switch (texture->target) { + case GL_TEXTURE_1D: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } + gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_1D); + checkGLcall("glEnable(GL_TEXTURE_1D)"); + break; case GL_TEXTURE_2D: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); checkGLcall("glDisable(GL_TEXTURE_3D)"); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) @@ -5080,6 +5634,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st checkGLcall("glEnable(GL_TEXTURE_2D)"); break; case GL_TEXTURE_RECTANGLE_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); @@ -5103,12 +5659,16 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB); checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); } + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D); checkGLcall("glEnable(GL_TEXTURE_3D)"); break; case GL_TEXTURE_CUBE_MAP_ARB: + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); @@ -5125,6 +5685,8 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st } else { + gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D); + checkGLcall("glDisable(GL_TEXTURE_1D)"); gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); checkGLcall("glEnable(GL_TEXTURE_2D)"); gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D); @@ -5178,10 +5740,10 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, const struct wined3d_d3d_info *d3d_info = context->d3d_info; unsigned int coord_idx, i; + memset(settings, 0, sizeof(*settings)); + if (si->position_transformed) { - memset(settings, 0, sizeof(*settings)); - settings->transformed = 1; settings->point_size = state->gl_primitive_type == GL_POINTS; settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE); @@ -5207,6 +5769,8 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, else settings->flatshading = FALSE; + settings->swizzle_map = si->swizzle_map; + return; } @@ -5223,7 +5787,6 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, break; } - settings->transformed = 0; settings->clipping = state->render_states[WINED3D_RS_CLIPPING] && state->render_states[WINED3D_RS_CLIPPLANEENABLE]; settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL)); @@ -5248,7 +5811,6 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, settings->specular_source = WINED3D_MCS_MATERIAL; } - settings->texcoords = 0; for (i = 0; i < MAX_TEXTURES; ++i) { coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; @@ -5259,15 +5821,31 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info)) settings->texcoords = (1u << MAX_TEXTURES) - 1; - settings->light_type = 0; for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) { - if (state->lights[i]) - settings->light_type |= (state->lights[i]->OriginalParms.type - & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i); + if (!state->lights[i]) + continue; + + switch (state->lights[i]->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + ++settings->point_light_count; + break; + case WINED3D_LIGHT_SPOT: + ++settings->spot_light_count; + break; + case WINED3D_LIGHT_DIRECTIONAL: + ++settings->directional_light_count; + break; + case WINED3D_LIGHT_PARALLELPOINT: + ++settings->parallel_point_light_count; + break; + default: + FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); + break; + } } - settings->ortho_fog = 0; if (!state->render_states[WINED3D_RS_FOGENABLE]) settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) @@ -5292,7 +5870,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, else settings->flatshading = FALSE; - settings->padding = 0; + settings->swizzle_map = si->swizzle_map; } int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry) @@ -5304,30 +5882,6 @@ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb return memcmp(ka, kb, sizeof(*ka)); } -const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) -{ - static const struct blit_shader * const blitters[] = - { - &arbfp_blit, - &ffp_blit, - &cpu_blit, - }; - unsigned int i; - - for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i) - { - if (blitters[i]->blit_supported(gl_info, d3d_info, blit_op, - src_rect, src_usage, src_pool, src_format, - dst_rect, dst_usage, dst_pool, dst_format)) - return blitters[i]; - } - - return NULL; -} - void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) { const struct wined3d_viewport *vp = &state->viewport; @@ -5340,14 +5894,22 @@ void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) const char *wined3d_debug_location(DWORD location) { + const char *prefix = ""; + const char *suffix = ""; char buf[294]; + if (wined3d_popcount(location) > 16) + { + prefix = "~("; + location = ~location; + suffix = ")"; + } + buf[0] = '\0'; #define LOCATION_TO_STR(u) if (location & u) { strcat(buf, " | "#u); location &= ~u; } LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED); LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM); LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY); - LOCATION_TO_STR(WINED3D_LOCATION_DIB); LOCATION_TO_STR(WINED3D_LOCATION_BUFFER); LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB); LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB); @@ -5357,7 +5919,7 @@ const char *wined3d_debug_location(DWORD location) #undef LOCATION_TO_STR if (location) FIXME("Unrecognized location flag(s) %#x.\n", location); - return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0"; + return wine_dbg_sprintf("%s%s%s", prefix, buf[0] ? &buf[3] : "0", suffix); } /* Print a floating point value with the %.8e format specifier, always using @@ -5412,3 +5974,79 @@ BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) return TRUE; } + +void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) +{ + unsigned int i; + + *base = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + *count = gl_limits->uniform_blocks[i]; + if (i == shader_type) + return; + *base += *count; + } + + ERR("Unrecognized shader type %#x.\n", shader_type); + *count = 0; +} + +void wined3d_gl_limits_get_texture_unit_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) +{ + unsigned int i; + + if (shader_type == WINED3D_SHADER_TYPE_COMPUTE) + { + if (gl_limits->combined_samplers == gl_limits->graphics_samplers) + *base = 0; + else + *base = gl_limits->graphics_samplers; + *count = gl_limits->samplers[WINED3D_SHADER_TYPE_COMPUTE]; + return; + } + + *base = 0; + for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i) + { + *count = gl_limits->samplers[i]; + if (i == shader_type) + return; + *base += *count; + } + + ERR("Unrecognized shader type %#x.\n", shader_type); + *count = 0; +} + +BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) +{ + SIZE_T max_capacity, new_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(1, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = count; + + if (!*elements) + new_elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_capacity * size); + else + new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); + if (!new_elements) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + return TRUE; +} diff --git a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c index eba814c9fc2..990aab00498 100644 --- a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c @@ -48,14 +48,14 @@ ULONG CDECL wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration return refcount; } -#if defined(STAGING_CSMT) -void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) +static void wined3d_vertex_declaration_destroy_object(void *object) { + struct wined3d_vertex_declaration *declaration = object; + HeapFree(GetProcessHeap(), 0, declaration->elements); HeapFree(GetProcessHeap(), 0, declaration); } -#endif /* STAGING_CSMT */ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration) { ULONG refcount = InterlockedDecrement(&declaration->ref); @@ -64,15 +64,9 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration if (!refcount) { -#if defined(STAGING_CSMT) - const struct wined3d_device *device = declaration->device; declaration->parent_ops->wined3d_object_destroyed(declaration->parent); - wined3d_cs_emit_vertex_declaration_destroy(device->cs, declaration); -#else /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, declaration->elements); - declaration->parent_ops->wined3d_object_destroyed(declaration->parent); - HeapFree(GetProcessHeap(), 0, declaration); -#endif /* STAGING_CSMT */ + wined3d_cs_destroy_object(declaration->device->cs, + wined3d_vertex_declaration_destroy_object, declaration); } return refcount; @@ -192,8 +186,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara declaration->parent = parent; declaration->parent_ops = parent_ops; declaration->device = device; - declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count); - if (!declaration->elements) + if (!(declaration->elements = wined3d_calloc(element_count, sizeof(*declaration->elements)))) { ERR("Failed to allocate elements memory.\n"); return E_OUTOFMEMORY; @@ -206,7 +199,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara { struct wined3d_vertex_declaration_element *e = &declaration->elements[i]; - e->format = wined3d_get_format(gl_info, elements[i].format); + e->format = wined3d_get_format(gl_info, elements[i].format, 0); e->ffp_valid = declaration_element_valid_ffp(&elements[i]); e->input_slot = elements[i].input_slot; e->offset = elements[i].offset; @@ -319,8 +312,8 @@ static void append_decl_element(struct wined3d_fvf_convert_state *state, elements[idx].usage = usage; elements[idx].usage_idx = usage_idx; - format = wined3d_get_format(state->gl_info, format_id); - state->offset += format->component_count * format->component_size; + format = wined3d_get_format(state->gl_info, format_id, 0); + state->offset += format->attribute_size; ++state->idx; } @@ -351,8 +344,8 @@ static unsigned int convert_fvf_to_declaration(const struct wined3d_gl_info *gl_ has_psize + has_diffuse + has_specular + num_textures; state.gl_info = gl_info; - state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements)); - if (!state.elements) return ~0U; + if (!(state.elements = wined3d_calloc(size, sizeof(*state.elements)))) + return ~0u; state.offset = 0; state.idx = 0; diff --git a/reactos/dll/directx/wine/wined3d/view.c b/reactos/dll/directx/wine/wined3d/view.c index 3f3682e502e..1f39dd18ee1 100644 --- a/reactos/dll/directx/wine/wined3d/view.c +++ b/reactos/dll/directx/wine/wined3d/view.c @@ -21,6 +21,282 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); +#define WINED3D_VIEW_CUBE_ARRAY (WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY) + +static BOOL is_stencil_view_format(const struct wined3d_format *format) +{ + return format->id == WINED3DFMT_X24_TYPELESS_G8_UINT + || format->id == WINED3DFMT_X32_TYPELESS_G8X24_UINT; +} + +static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, + const struct wined3d_view_desc *desc, const struct wined3d_texture *texture) +{ + static const struct + { + GLenum texture_target; + unsigned int view_flags; + GLenum view_target; + enum wined3d_gl_extension extension; + } + view_types[] = + { + {GL_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_CUBE_MAP}, + {GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_RECTANGLE}, + {GL_TEXTURE_1D, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, + {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D}, + {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, + {GL_TEXTURE_2D, 0, GL_TEXTURE_2D}, + {GL_TEXTURE_2D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY}, + {GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_2D}, + {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY}, + {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_CUBE, GL_TEXTURE_CUBE_MAP}, + {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_CUBE_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, ARB_TEXTURE_CUBE_MAP_ARRAY}, + {GL_TEXTURE_3D, 0, GL_TEXTURE_3D}, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(view_types); ++i) + { + if (view_types[i].texture_target != texture->target || view_types[i].view_flags != desc->flags) + continue; + if (gl_info->supported[view_types[i].extension]) + return view_types[i].view_target; + + FIXME("Extension %#x not supported.\n", view_types[i].extension); + } + + FIXME("Unhandled view flags %#x for texture target %#x.\n", desc->flags, texture->target); + return texture->target; +} + +static const struct wined3d_format *validate_resource_view(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, BOOL mip_slice) +{ + const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; + const struct wined3d_format *format; + + format = wined3d_get_format(gl_info, desc->format_id, resource->usage); + if (resource->type == WINED3D_RTYPE_BUFFER && (desc->flags & WINED3D_VIEW_BUFFER_RAW)) + { + if (format->id != WINED3DFMT_R32_TYPELESS) + { + WARN("Invalid format %s for raw buffer view.\n", debug_d3dformat(format->id)); + return NULL; + } + + format = wined3d_get_format(gl_info, WINED3DFMT_R32_UINT, resource->usage); + } + + if (wined3d_format_is_typeless(format)) + { + WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(format->id)); + return NULL; + } + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_buffer *buffer = buffer_from_resource(resource); + unsigned int buffer_size, element_size; + + if (buffer->desc.structure_byte_stride) + { + if (desc->format_id != WINED3DFMT_UNKNOWN) + { + WARN("Invalid format %s for structured buffer view.\n", debug_d3dformat(desc->format_id)); + return NULL; + } + + format = wined3d_get_format(gl_info, WINED3DFMT_R32_UINT, resource->usage); + element_size = buffer->desc.structure_byte_stride; + } + else + { + element_size = format->byte_count; + } + + if (!element_size) + return NULL; + + buffer_size = buffer->resource.size / element_size; + if (desc->u.buffer.start_idx >= buffer_size + || desc->u.buffer.count > buffer_size - desc->u.buffer.start_idx) + return NULL; + } + else + { + struct wined3d_texture *texture = texture_from_resource(resource); + unsigned int depth_or_layer_count; + + if (mip_slice && resource->type == WINED3D_RTYPE_TEXTURE_3D) + depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + else + depth_or_layer_count = texture->layer_count; + + if (!desc->u.texture.level_count + || (mip_slice && desc->u.texture.level_count != 1) + || desc->u.texture.level_idx >= texture->level_count + || desc->u.texture.level_count > texture->level_count - desc->u.texture.level_idx + || !desc->u.texture.layer_count + || desc->u.texture.layer_idx >= depth_or_layer_count + || desc->u.texture.layer_count > depth_or_layer_count - desc->u.texture.layer_idx) + return NULL; + } + + return format; +} + +static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target, + const struct wined3d_view_desc *desc, struct wined3d_texture *texture, + const struct wined3d_format *view_format) +{ + const struct wined3d_gl_info *gl_info; + unsigned int layer_idx, layer_count; + struct wined3d_context *context; + GLuint texture_name; + + view->target = view_target; + + context = context_acquire(texture->resource.device, NULL, 0); + gl_info = context->gl_info; + + if (!gl_info->supported[ARB_TEXTURE_VIEW]) + { + context_release(context); + FIXME("OpenGL implementation does not support texture views.\n"); + return; + } + + wined3d_texture_prepare_texture(texture, context, FALSE); + texture_name = wined3d_texture_get_texture_name(texture, context, FALSE); + + layer_idx = desc->u.texture.layer_idx; + layer_count = desc->u.texture.layer_count; + if (view_target == GL_TEXTURE_3D && (layer_idx || layer_count != 1)) + { + FIXME("Depth slice (%u-%u) not supported.\n", layer_idx, layer_count); + layer_idx = 0; + layer_count = 1; + } + + gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); + GL_EXTCALL(glTextureView(view->name, view->target, texture_name, view_format->glInternal, + desc->u.texture.level_idx, desc->u.texture.level_count, + layer_idx, layer_count)); + checkGLcall("Create texture view"); + + if (is_stencil_view_format(view_format)) + { + static const GLint swizzle[] = {GL_ZERO, GL_RED, GL_ZERO, GL_ZERO}; + + if (!gl_info->supported[ARB_STENCIL_TEXTURING]) + { + context_release(context); + FIXME("OpenGL implementation does not support stencil texturing.\n"); + return; + } + + context_bind_texture(context, view->target, view->name); + gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + gl_info->gl_ops.gl.p_glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); + checkGLcall("Initialize stencil view"); + + context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + } + + context_release(context); +} + +static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context *context, + struct wined3d_buffer *buffer, const struct wined3d_format *view_format, + unsigned int offset, unsigned int size) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) + { + FIXME("OpenGL implementation does not support buffer textures.\n"); + return; + } + + if ((offset & (gl_info->limits.texture_buffer_offset_alignment - 1))) + { + FIXME("Buffer offset %u is not %u byte aligned.\n", + offset, gl_info->limits.texture_buffer_offset_alignment); + return; + } + + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); + + view->target = GL_TEXTURE_BUFFER; + gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); + + context_bind_texture(context, GL_TEXTURE_BUFFER, view->name); + if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) + { + GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format->glInternal, + buffer->buffer_object, offset, size)); + } + else + { + if (offset || size != buffer->resource.size) + FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n"); + GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object)); + } + checkGLcall("Create buffer texture"); + + context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); +} + +static void get_buffer_view_range(const struct wined3d_buffer *buffer, + const struct wined3d_view_desc *desc, const struct wined3d_format *view_format, + unsigned int *offset, unsigned int *size) +{ + if (desc->format_id == WINED3DFMT_UNKNOWN) + { + *offset = desc->u.buffer.start_idx * buffer->desc.structure_byte_stride; + *size = desc->u.buffer.count * buffer->desc.structure_byte_stride; + } + else + { + *offset = desc->u.buffer.start_idx * view_format->byte_count; + *size = desc->u.buffer.count * view_format->byte_count; + } +} + +static void create_buffer_view(struct wined3d_gl_view *view, struct wined3d_context *context, + const struct wined3d_view_desc *desc, struct wined3d_buffer *buffer, + const struct wined3d_format *view_format) +{ + unsigned int offset, size; + + get_buffer_view_range(buffer, desc, view_format, &offset, &size); + create_buffer_texture(view, context, buffer, view_format, offset, size); +} + +static void wined3d_view_invalidate_location(struct wined3d_resource *resource, + const struct wined3d_view_desc *desc, DWORD location) +{ + unsigned int i, sub_resource_idx, layer_count; + struct wined3d_texture *texture; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + wined3d_buffer_invalidate_location(buffer_from_resource(resource), location); + return; + } + + texture = texture_from_resource(resource); + + sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx; + layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? desc->u.texture.layer_count : 1; + for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) + wined3d_texture_invalidate_location(texture, sub_resource_idx, location); +} + ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view) { ULONG refcount = InterlockedIncrement(&view->refcount); @@ -30,13 +306,27 @@ ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *v return refcount; } -#if defined(STAGING_CSMT) -void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) +static void wined3d_rendertarget_view_destroy_object(void *object) { + struct wined3d_rendertarget_view *view = object; + struct wined3d_device *device = view->resource->device; + + if (view->gl_view.name) + { + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + context = context_acquire(device, NULL, 0); + gl_info = context->gl_info; + context_gl_resource_released(device, view->gl_view.name, FALSE); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); + checkGLcall("glDeleteTextures"); + context_release(context); + } + HeapFree(GetProcessHeap(), 0, view); } -#endif /* STAGING_CSMT */ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) { ULONG refcount = InterlockedDecrement(&view->refcount); @@ -45,21 +335,14 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v if (!refcount) { -#if defined(STAGING_CSMT) - struct wined3d_device *device = view->resource->device; + struct wined3d_resource *resource = view->resource; + struct wined3d_device *device = resource->device; /* Call wined3d_object_destroyed() before releasing the resource, * since releasing the resource may end up destroying the parent. */ view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_resource_decref(view->resource); - wined3d_cs_emit_view_destroy(device->cs, view); -#else /* STAGING_CSMT */ - /* Call wined3d_object_destroyed() before releasing the resource, - * since releasing the resource may end up destroying the parent. */ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_resource_decref(view->resource); - HeapFree(GetProcessHeap(), 0, view); -#endif /* STAGING_CSMT */ + wined3d_cs_destroy_object(device->cs, wined3d_rendertarget_view_destroy_object, view); + wined3d_resource_decref(resource); } return refcount; @@ -74,18 +357,16 @@ void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertar void * CDECL wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view) { - struct wined3d_resource *sub_resource; + struct wined3d_texture *texture; TRACE("view %p.\n", view); if (view->resource->type == WINED3D_RTYPE_BUFFER) return wined3d_buffer_get_parent(buffer_from_resource(view->resource)); - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(view->resource), - view->sub_resource_idx))) - return NULL; + texture = texture_from_resource(view->resource); - return wined3d_resource_get_parent(sub_resource); + return texture->sub_resources[view->sub_resource_idx].parent; } void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent) @@ -102,48 +383,197 @@ struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const str return view->resource; } -static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, - const struct wined3d_rendertarget_view_desc *desc, struct wined3d_resource *resource, - void *parent, const struct wined3d_parent_ops *parent_ops) +void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view, + const struct wined3d_context *context, unsigned int *width, unsigned int *height) { - const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; + const struct wined3d_texture *texture; - view->refcount = 1; - view->resource = resource; - wined3d_resource_incref(resource); - view->parent = parent; - view->parent_ops = parent_ops; - - view->format = wined3d_get_format(gl_info, desc->format_id); - view->format_flags = view->format->flags[resource->gl_type]; - if (resource->type == WINED3D_RTYPE_BUFFER) + if (view->resource->type != WINED3D_RTYPE_TEXTURE_2D) { - view->sub_resource_idx = 0; - view->buffer_offset = desc->u.buffer.start_idx; - view->width = desc->u.buffer.count; - view->height = 1; - view->depth = 1; + *width = view->width; + *height = view->height; + return; + } + + texture = texture_from_resource(view->resource); + if (texture->swapchain) + { + /* The drawable size of an onscreen drawable is the surface size. + * (Actually: The window size, but the surface is created in window + * size.) */ + *width = texture->resource.width; + *height = texture->resource.height; + } + else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + { + const struct wined3d_swapchain *swapchain = context->swapchain; + + /* The drawable size of a backbuffer / aux buffer offscreen target is + * the size of the current context's drawable, which is the size of + * the back buffer of the swapchain the active context belongs to. */ + *width = swapchain->desc.backbuffer_width; + *height = swapchain->desc.backbuffer_height; } else { - struct wined3d_texture *texture = wined3d_texture_from_resource(resource); - struct wined3d_resource *sub_resource; + unsigned int level_idx = view->sub_resource_idx % texture->level_count; - view->sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx; - sub_resource = wined3d_texture_get_sub_resource(texture, view->sub_resource_idx); - - view->buffer_offset = 0; - view->width = sub_resource->width; - view->height = sub_resource->height; - view->depth = desc->u.texture.layer_count; + /* The drawable size of an FBO target is the OpenGL texture size, + * which is the power of two size. */ + *width = wined3d_texture_get_level_pow2_width(texture, level_idx); + *height = wined3d_texture_get_level_pow2_height(texture, level_idx); } } -HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, +void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view *view, + struct wined3d_context *context, DWORD location) +{ + struct wined3d_resource *resource = view->resource; + unsigned int i, sub_resource_idx, layer_count; + struct wined3d_texture *texture; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type)); + return; + } + + texture = texture_from_resource(resource); + sub_resource_idx = view->sub_resource_idx; + layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1; + for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) + wined3d_texture_prepare_location(texture, sub_resource_idx, context, location); +} + +void wined3d_rendertarget_view_load_location(struct wined3d_rendertarget_view *view, + struct wined3d_context *context, DWORD location) +{ + struct wined3d_resource *resource = view->resource; + unsigned int i, sub_resource_idx, layer_count; + struct wined3d_texture *texture; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + wined3d_buffer_load_location(buffer_from_resource(resource), context, location); + return; + } + + texture = texture_from_resource(resource); + sub_resource_idx = view->sub_resource_idx; + layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1; + for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) + wined3d_texture_load_location(texture, sub_resource_idx, context, location); +} + +void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, DWORD location) +{ + struct wined3d_resource *resource = view->resource; + unsigned int i, sub_resource_idx, layer_count; + struct wined3d_texture *texture; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type)); + return; + } + + texture = texture_from_resource(resource); + sub_resource_idx = view->sub_resource_idx; + layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1; + for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) + wined3d_texture_validate_location(texture, sub_resource_idx, location); +} + +void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view, DWORD location) +{ + wined3d_view_invalidate_location(view->resource, &view->desc, location); +} + +static void wined3d_render_target_view_cs_init(void *object) +{ + struct wined3d_rendertarget_view *view = object; + struct wined3d_resource *resource = view->resource; + const struct wined3d_view_desc *desc = &view->desc; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type)); + } + else + { + struct wined3d_texture *texture = texture_from_resource(resource); + unsigned int depth_or_layer_count; + + if (resource->type == WINED3D_RTYPE_TEXTURE_3D) + depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + else + depth_or_layer_count = texture->layer_count; + + if (resource->format->id != view->format->id + || (view->layer_count != 1 && view->layer_count != depth_or_layer_count)) + { + if (resource->format->gl_view_class != view->format->gl_view_class) + { + FIXME("Render target view not supported, resource format %s, view format %s.\n", + debug_d3dformat(resource->format->id), debug_d3dformat(view->format->id)); + return; + } + if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1) + { + FIXME("Swapchain views not supported.\n"); + return; + } + + create_texture_view(&view->gl_view, texture->target, desc, texture, view->format); + } + } +} + +static HRESULT wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + view->refcount = 1; + view->parent = parent; + view->parent_ops = parent_ops; + + if (!(view->format = validate_resource_view(desc, resource, TRUE))) + return E_INVALIDARG; + view->format_flags = view->format->flags[resource->gl_type]; + view->desc = *desc; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + view->sub_resource_idx = 0; + view->layer_count = 1; + view->width = desc->u.buffer.count; + view->height = 1; + } + else + { + struct wined3d_texture *texture = texture_from_resource(resource); + + view->sub_resource_idx = desc->u.texture.level_idx; + if (resource->type != WINED3D_RTYPE_TEXTURE_3D) + view->sub_resource_idx += desc->u.texture.layer_idx * texture->level_count; + view->layer_count = desc->u.texture.layer_count; + view->width = wined3d_texture_get_level_width(texture, desc->u.texture.level_idx); + view->height = wined3d_texture_get_level_height(texture, desc->u.texture.level_idx); + } + + wined3d_resource_incref(view->resource = resource); + + wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_cs_init, view); + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view) { struct wined3d_rendertarget_view *object; + HRESULT hr; TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", desc, resource, parent, parent_ops, view); @@ -151,25 +581,32 @@ HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_rendertarget if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops); + if (FAILED(hr = wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops))) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to initialise view, hr %#x.\n", hr); + return hr; + } TRACE("Created render target view %p.\n", object); *view = object; - return WINED3D_OK; + return hr; } HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view) { - struct wined3d_rendertarget_view_desc desc; + struct wined3d_view_desc desc; TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n", texture, sub_resource_idx, parent, parent_ops, view); desc.format_id = texture->resource.format->id; + desc.flags = 0; desc.u.texture.level_idx = sub_resource_idx % texture->level_count; + desc.u.texture.level_count = 1; desc.u.texture.layer_idx = sub_resource_idx / texture->level_count; desc.u.texture.layer_count = 1; @@ -185,6 +622,25 @@ ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_v return refcount; } +static void wined3d_shader_resource_view_destroy_object(void *object) +{ + struct wined3d_shader_resource_view *view = object; + + if (view->gl_view.name) + { + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + context = context_acquire(view->resource->device, NULL, 0); + gl_info = context->gl_info; + gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); + checkGLcall("glDeleteTextures"); + context_release(context); + } + + HeapFree(GetProcessHeap(), 0, view); +} + ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view) { ULONG refcount = InterlockedDecrement(&view->refcount); @@ -193,11 +649,14 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v if (!refcount) { + struct wined3d_resource *resource = view->resource; + struct wined3d_device *device = resource->device; + /* Call wined3d_object_destroyed() before releasing the resource, * since releasing the resource may end up destroying the parent. */ view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_resource_decref(view->resource); - HeapFree(GetProcessHeap(), 0, view); + wined3d_cs_destroy_object(device->cs, wined3d_shader_resource_view_destroy_object, view); + wined3d_resource_decref(resource); } return refcount; @@ -210,24 +669,340 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader return view->parent; } -HRESULT CDECL wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent, - const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view) +static void wined3d_shader_resource_view_cs_init(void *object) +{ + struct wined3d_shader_resource_view *view = object; + struct wined3d_resource *resource = view->resource; + const struct wined3d_format *view_format; + const struct wined3d_gl_info *gl_info; + const struct wined3d_view_desc *desc; + GLenum view_target; + + view_format = view->format; + gl_info = &resource->device->adapter->gl_info; + desc = &view->desc; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_buffer *buffer = buffer_from_resource(resource); + struct wined3d_context *context; + + context = context_acquire(resource->device, NULL, 0); + create_buffer_view(&view->gl_view, context, desc, buffer, view_format); + context_release(context); + } + else + { + struct wined3d_texture *texture = texture_from_resource(resource); + + view_target = get_texture_view_target(gl_info, desc, texture); + + if (resource->format->id == view_format->id && texture->target == view_target + && !desc->u.texture.level_idx && desc->u.texture.level_count == texture->level_count + && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture->layer_count + && !is_stencil_view_format(view_format)) + { + TRACE("Creating identity shader resource view.\n"); + } + else if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1) + { + FIXME("Swapchain shader resource views not supported.\n"); + } + else if (resource->format->typeless_id == view_format->typeless_id + && resource->format->gl_view_class == view_format->gl_view_class) + { + create_texture_view(&view->gl_view, view_target, desc, texture, view_format); + } + else + { + FIXME("Shader resource view not supported, resource format %s, view format %s.\n", + debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id)); + } + } +#if defined(STAGING_CSMT) + + wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ +} + +static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + view->refcount = 1; + view->parent = parent; + view->parent_ops = parent_ops; + + if (!(view->format = validate_resource_view(desc, resource, FALSE))) + return E_INVALIDARG; + view->desc = *desc; + + wined3d_resource_incref(view->resource = resource); + +#if defined(STAGING_CSMT) + wined3d_resource_acquire(resource); +#endif /* STAGING_CSMT */ + wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view); + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view) { struct wined3d_shader_resource_view *object; + HRESULT hr; - TRACE("resource %p, parent %p, parent_ops %p, view %p.\n", resource, parent, parent_ops, view); + TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", + desc, resource, parent, parent_ops, view); if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - object->refcount = 1; - object->resource = resource; - wined3d_resource_incref(resource); - object->parent = parent; - object->parent_ops = parent_ops; + if (FAILED(hr = wined3d_shader_resource_view_init(object, desc, resource, parent, parent_ops))) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to initialise view, hr %#x.\n", hr); + return hr; + } TRACE("Created shader resource view %p.\n", object); *view = object; return WINED3D_OK; } + +void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view, + unsigned int unit, struct wined3d_sampler *sampler, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture *texture; + + context_active_texture(context, gl_info, unit); + + if (view->gl_view.name) + { + context_bind_texture(context, view->gl_view.target, view->gl_view.name); + wined3d_sampler_bind(sampler, unit, NULL, context); + return; + } + + if (view->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Buffer shader resources not supported.\n"); + return; + } + + texture = wined3d_texture_from_resource(view->resource); + wined3d_texture_bind(texture, context, FALSE); + wined3d_sampler_bind(sampler, unit, texture, context); +} + +ULONG CDECL wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view *view) +{ + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + return refcount; +} + +static void wined3d_unordered_access_view_destroy_object(void *object) +{ + struct wined3d_unordered_access_view *view = object; + + if (view->gl_view.name || view->counter_bo) + { + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + + context = context_acquire(view->resource->device, NULL, 0); + gl_info = context->gl_info; + if (view->gl_view.name) + gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->gl_view.name); + if (view->counter_bo) + GL_EXTCALL(glDeleteBuffers(1, &view->counter_bo)); + checkGLcall("delete resources"); + context_release(context); + } + + HeapFree(GetProcessHeap(), 0, view); +} + +ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view) +{ + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + struct wined3d_resource *resource = view->resource; + struct wined3d_device *device = resource->device; + + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_cs_destroy_object(device->cs, wined3d_unordered_access_view_destroy_object, view); + wined3d_resource_decref(resource); + } + + return refcount; +} + +void * CDECL wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view *view) +{ + TRACE("view %p.\n", view); + + return view->parent; +} + +void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view, + DWORD location) +{ + wined3d_view_invalidate_location(view->resource, &view->desc, location); +} + +void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view, + const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_format *format; + struct wined3d_resource *resource; + struct wined3d_buffer *buffer; + unsigned int offset, size; + + resource = view->resource; + if (resource->type != WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + return; + } + + if (!gl_info->supported[ARB_CLEAR_BUFFER_OBJECT]) + { + FIXME("OpenGL implementation does not support ARB_clear_buffer_object.\n"); + return; + } + + format = view->format; + if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT + && format->id != WINED3DFMT_R32G32B32A32_UINT + && format->id != WINED3DFMT_R32G32B32A32_SINT) + { + FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id)); + return; + } + + buffer = buffer_from_resource(resource); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); + wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); + + get_buffer_view_range(buffer, &view->desc, format, &offset, &size); + context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object); + GL_EXTCALL(glClearBufferSubData(buffer->buffer_type_hint, format->glInternal, + offset, size, format->glFormat, format->glType, clear_value)); + checkGLcall("clear unordered access view"); +} + +static void wined3d_unordered_access_view_cs_init(void *object) +{ + struct wined3d_unordered_access_view *view = object; + struct wined3d_resource *resource = view->resource; + struct wined3d_view_desc *desc = &view->desc; + const struct wined3d_gl_info *gl_info; + + gl_info = &resource->device->adapter->gl_info; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_buffer *buffer = buffer_from_resource(resource); + struct wined3d_context *context; + + context = context_acquire(resource->device, NULL, 0); + gl_info = context->gl_info; + create_buffer_view(&view->gl_view, context, desc, buffer, view->format); + if (desc->flags & WINED3D_VIEW_BUFFER_COUNTER) + { + static const GLuint initial_value = 0; + GL_EXTCALL(glGenBuffers(1, &view->counter_bo)); + GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo)); + GL_EXTCALL(glBufferData(GL_ATOMIC_COUNTER_BUFFER, + sizeof(initial_value), &initial_value, GL_STATIC_DRAW)); + checkGLcall("create atomic counter buffer"); + } + context_release(context); + } + else + { + struct wined3d_texture *texture = texture_from_resource(resource); + unsigned int depth_or_layer_count; + + if (resource->type == WINED3D_RTYPE_TEXTURE_3D) + depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + else + depth_or_layer_count = texture->layer_count; + + if (desc->u.texture.layer_idx || desc->u.texture.layer_count != depth_or_layer_count) + { + create_texture_view(&view->gl_view, get_texture_view_target(gl_info, desc, texture), + desc, texture, view->format); + } + } +#if defined(STAGING_CSMT) + + wined3d_resource_release(resource); +#endif /* STAGING_CSMT */ +} + +static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view, + const struct wined3d_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + view->refcount = 1; + view->parent = parent; + view->parent_ops = parent_ops; + + if (!(view->format = validate_resource_view(desc, resource, TRUE))) + return E_INVALIDARG; + view->desc = *desc; + + if (desc->flags & WINED3D_VIEW_BUFFER_APPEND) + FIXME("Unhandled view flags %#x.\n", desc->flags); + + wined3d_resource_incref(view->resource = resource); + +#if defined(STAGING_CSMT) + wined3d_resource_acquire(resource); +#endif /* STAGING_CSMT */ + wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view); + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view) +{ + struct wined3d_unordered_access_view *object; + HRESULT hr; + + TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", + desc, resource, parent, parent_ops, view); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_unordered_access_view_init(object, desc, resource, parent, parent_ops))) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to initialise view, hr %#x.\n", hr); + return hr; + } + + TRACE("Created unordered access view %p.\n", object); + *view = object; + + return WINED3D_OK; +} diff --git a/reactos/dll/directx/wine/wined3d/volume.c b/reactos/dll/directx/wine/wined3d/volume.c deleted file mode 100644 index 672c4f0ce7c..00000000000 --- a/reactos/dll/directx/wine/wined3d/volume.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * Copyright 2002-2005 Jason Edmeades - * Copyright 2002-2005 Raphael Junqueira - * Copyright 2005 Oliver Stieber - * Copyright 2009-2011 Henri Verbeet for CodeWeavers - * Copyright 2013 Stefan Dösinger for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "wined3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); -WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); - -BOOL volume_prepare_system_memory(struct wined3d_volume *volume) -{ - if (volume->resource.heap_memory) - return TRUE; - - if (!wined3d_resource_allocate_sysmem(&volume->resource)) - { - ERR("Failed to allocate system memory.\n"); - return FALSE; - } - return TRUE; -} - -/* This call just uploads data, the caller is responsible for binding the - * correct texture. */ -/* Context activation is done by the caller. */ -void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_const_bo_address *data) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_format *format = volume->resource.format; - UINT width = volume->resource.width; - UINT height = volume->resource.height; - UINT depth = volume->resource.depth; - const void *mem = data->addr; - void *converted_mem = NULL; - - TRACE("volume %p, context %p, level %u, format %s (%#x).\n", - volume, context, volume->texture_level, debug_d3dformat(format->id), - format->id); - - if (format->convert) - { - UINT dst_row_pitch, dst_slice_pitch; - UINT src_row_pitch, src_slice_pitch; - - if (data->buffer_object) - ERR("Loading a converted volume from a PBO.\n"); - if (volume->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) - ERR("Converting a block-based format.\n"); - - dst_row_pitch = width * format->conv_byte_count; - dst_slice_pitch = dst_row_pitch * height; - -#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&volume->resource, &src_row_pitch, &src_slice_pitch); -#else /* STAGING_CSMT */ - wined3d_texture_get_pitch(volume->container, volume->texture_level, &src_row_pitch, &src_slice_pitch); -#endif /* STAGING_CSMT */ - - converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); - format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch, - dst_row_pitch, dst_slice_pitch, width, height, depth); - mem = converted_mem; - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, - width, height, depth, - format->glFormat, format->glType, mem)); - checkGLcall("glTexSubImage3D"); - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - - HeapFree(GetProcessHeap(), 0, converted_mem); -} - -#if !defined(STAGING_CSMT) -void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) -{ - TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location)); - volume->locations |= location; - TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); -} - -void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) -{ - TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location)); - volume->locations &= ~location; - TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); -} - -#endif /* STAGING_CSMT */ -/* Context activation is done by the caller. */ -static void wined3d_volume_download_data(struct wined3d_volume *volume, - const struct wined3d_context *context, const struct wined3d_bo_address *data) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_format *format = volume->resource.format; - - if (format->convert) - { - FIXME("Attempting to download a converted volume, format %s.\n", - debug_d3dformat(format->id)); - return; - } - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); - checkGLcall("glBindBuffer"); - } - - gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, volume->texture_level, - format->glFormat, format->glType, data->addr); - checkGLcall("glGetTexImage"); - - if (data->buffer_object) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); - checkGLcall("glBindBuffer"); - } - -} - -static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) -{ - wined3d_resource_free_sysmem(&volume->resource); -#if defined(STAGING_CSMT) - volume->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); -#else /* STAGING_CSMT */ - wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); -} - -static DWORD volume_access_from_location(DWORD location) -{ - switch (location) - { - case WINED3D_LOCATION_DISCARDED: - return 0; - - case WINED3D_LOCATION_SYSMEM: - return WINED3D_RESOURCE_ACCESS_CPU; - - case WINED3D_LOCATION_BUFFER: - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - return WINED3D_RESOURCE_ACCESS_GPU; - - default: - FIXME("Unhandled location %#x.\n", location); - return 0; - } -#endif /* STAGING_CSMT */ -} - -/* Context activation is done by the caller. */ -static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, - struct wined3d_context *context, BOOL dest_is_srgb) -{ - struct wined3d_bo_address data; - /* Optimizations are possible, but the effort should be put into either - * implementing EXT_SRGB_DECODE in the driver or finding out why we - * picked the wrong copy for the original upload and fixing that. - * - * Also keep in mind that we want to avoid using resource.heap_memory - * for DEFAULT pool surfaces. */ - - WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n"); - data.buffer_object = 0; - data.addr = HeapAlloc(GetProcessHeap(), 0, volume->resource.size); - if (!data.addr) - return; - - wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb); - wined3d_volume_download_data(volume, context, &data); - wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb); - wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data)); - - HeapFree(GetProcessHeap(), 0, data.addr); -} - -static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) -{ - if (volume->resource.pool != WINED3D_POOL_MANAGED) - return FALSE; - if (volume->download_count >= 10) - return FALSE; - if (volume->resource.format->convert) - return FALSE; - - return TRUE; -} -#if defined(STAGING_CSMT) - -/* Context activation is done by the caller. */ -static void wined3d_volume_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -{ - struct wined3d_volume *volume = volume_from_resource(resource); - DWORD required_access = wined3d_resource_access_from_location(location); - - TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), - wined3d_debug_location(volume->resource.locations)); -#else /* STAGING_CSMT */ -/* Context activation is done by the caller. */ -static void wined3d_volume_load_location(struct wined3d_volume *volume, - struct wined3d_context *context, DWORD location) -{ - DWORD required_access = volume_access_from_location(location); - - TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), - wined3d_debug_location(volume->locations)); - - if ((volume->locations & location) == location) - { - TRACE("Location(s) already up to date.\n"); - return; - } -#endif /* STAGING_CSMT */ - - if ((volume->resource.access_flags & required_access) != required_access) - { - ERR("Operation requires %#x access, but volume only has %#x.\n", - required_access, volume->resource.access_flags); - return; - } - - switch (location) - { - case WINED3D_LOCATION_TEXTURE_RGB: - case WINED3D_LOCATION_TEXTURE_SRGB: - if ((location == WINED3D_LOCATION_TEXTURE_RGB - && !(volume->container->flags & WINED3D_TEXTURE_RGB_ALLOCATED)) - || (location == WINED3D_LOCATION_TEXTURE_SRGB - && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED))) - ERR("Trying to load (s)RGB texture without prior allocation.\n"); - -#if defined(STAGING_CSMT) - if (volume->resource.locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Volume previously discarded, nothing to do.\n"); - wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_DISCARDED); - } - else if (volume->resource.locations & WINED3D_LOCATION_SYSMEM) - { - struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; - wined3d_texture_bind_and_dirtify(volume->container, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_volume_upload_data(volume, context, &data); - } - else if (volume->resource.locations & WINED3D_LOCATION_BUFFER) - { - struct wined3d_const_bo_address data = {volume->resource.buffer->name, NULL}; - wined3d_texture_bind_and_dirtify(volume->container, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_volume_upload_data(volume, context, &data); - } - else if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) - { - wined3d_volume_srgb_transfer(volume, context, TRUE); - } - else if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_SRGB) - { - wined3d_volume_srgb_transfer(volume, context, FALSE); - } - else - { - FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->resource.locations)); - return; - } - wined3d_resource_validate_location(&volume->resource, location); -#else /* STAGING_CSMT */ - if (volume->locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Volume previously discarded, nothing to do.\n"); - wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); - } - else if (volume->locations & WINED3D_LOCATION_SYSMEM) - { - struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; - wined3d_texture_bind_and_dirtify(volume->container, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_volume_upload_data(volume, context, &data); - } - else if (volume->locations & WINED3D_LOCATION_BUFFER) - { - struct wined3d_const_bo_address data = {volume->pbo, NULL}; - wined3d_texture_bind_and_dirtify(volume->container, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_volume_upload_data(volume, context, &data); - } - else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) - { - wined3d_volume_srgb_transfer(volume, context, TRUE); - } - else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB) - { - wined3d_volume_srgb_transfer(volume, context, FALSE); - } - else - { - FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations)); - return; - } - wined3d_volume_validate_location(volume, location); -#endif /* STAGING_CSMT */ - - if (wined3d_volume_can_evict(volume)) - wined3d_volume_evict_sysmem(volume); - - break; - - case WINED3D_LOCATION_SYSMEM: - if (!volume->resource.heap_memory) - ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); - -#if defined(STAGING_CSMT) - if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, volume->resource.heap_memory}; - - if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) -#else /* STAGING_CSMT */ - if (volume->locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Volume previously discarded, nothing to do.\n"); - wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); - } - else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, volume->resource.heap_memory}; - - if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) -#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); - else - wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); - - volume->download_count++; - wined3d_volume_download_data(volume, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", -#if defined(STAGING_CSMT) - wined3d_debug_location(volume->resource.locations)); - return; - } - wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); - break; - - case WINED3D_LOCATION_BUFFER: - if (!volume->resource.buffer) - ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); - - if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {volume->resource.buffer->name, NULL}; - - if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) -#else /* STAGING_CSMT */ - wined3d_debug_location(volume->locations)); - return; - } - wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); - break; - - case WINED3D_LOCATION_BUFFER: - if (!volume->pbo) - ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); - - if (volume->locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Volume previously discarded, nothing to do.\n"); - wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); - } - else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {volume->pbo, NULL}; - - if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) -#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); - else - wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); - - wined3d_volume_download_data(volume, context, &data); - } - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", -#if defined(STAGING_CSMT) - wined3d_debug_location(volume->resource.locations)); - return; - } - wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_BUFFER); - break; - - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(volume->resource.locations)); -#else /* STAGING_CSMT */ - wined3d_debug_location(volume->locations)); - return; - } - wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); - break; - - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(volume->locations)); -#endif /* STAGING_CSMT */ - } -} - -/* Context activation is done by the caller. */ -void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) -{ - wined3d_texture_prepare_texture(volume->container, context, srgb_mode); -#if defined(STAGING_CSMT) - wined3d_resource_load_location(&volume->resource, context, - srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); -} - -void wined3d_volume_destroy(struct wined3d_volume *volume) -{ - struct wined3d_device *device = volume->resource.device; - TRACE("volume %p.\n", volume); - - resource_cleanup(&volume->resource); - volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); - wined3d_cs_emit_volume_cleanup(device->cs, volume); -#else /* STAGING_CSMT */ - wined3d_volume_load_location(volume, context, - srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); -} - -/* Context activation is done by the caller. */ -static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (volume->pbo) - return; - - GL_EXTCALL(glGenBuffers(1, &volume->pbo)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); - GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Create PBO"); - - TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume); -} - -static void wined3d_volume_free_pbo(struct wined3d_volume *volume) -{ - struct wined3d_context *context = context_acquire(volume->resource.device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; - - TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume); - GL_EXTCALL(glDeleteBuffers(1, &volume->pbo)); - checkGLcall("glDeleteBuffers"); - volume->pbo = 0; - context_release(context); -} - -void wined3d_volume_destroy(struct wined3d_volume *volume) -{ - TRACE("volume %p.\n", volume); - - if (volume->pbo) - wined3d_volume_free_pbo(volume); - - resource_cleanup(&volume->resource); - volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); - HeapFree(GetProcessHeap(), 0, volume); -#endif /* STAGING_CSMT */ -} - -static void volume_unload(struct wined3d_resource *resource) -{ - struct wined3d_volume *volume = volume_from_resource(resource); - struct wined3d_device *device = volume->resource.device; - struct wined3d_context *context; - - if (volume->resource.pool == WINED3D_POOL_DEFAULT) - ERR("Unloading DEFAULT pool volume.\n"); - - TRACE("texture %p.\n", resource); - -#if defined(STAGING_CSMT) - if (wined3d_resource_prepare_system_memory(&volume->resource)) - { - context = context_acquire(device, NULL); - wined3d_resource_load_location(&volume->resource, context, WINED3D_LOCATION_SYSMEM); - context_release(context); - wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_SYSMEM); - } - else - { - ERR("Out of memory when unloading volume %p.\n", volume); - wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_DISCARDED); - wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED); -#else /* STAGING_CSMT */ - if (volume_prepare_system_memory(volume)) - { - context = context_acquire(device, NULL); - wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); - context_release(context); - wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM); - } - else - { - ERR("Out of memory when unloading volume %p.\n", volume); - wined3d_volume_validate_location(volume, WINED3D_LOCATION_DISCARDED); - wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED); - } - - if (volume->pbo) - { - /* Should not happen because only dynamic default pool volumes - * have a buffer, and those are not evicted by device_evit_managed_resources - * and must be freed before a non-ex device reset. */ - ERR("Unloading a volume with a buffer\n"); - wined3d_volume_free_pbo(volume); -#endif /* STAGING_CSMT */ - } - - /* The texture name is managed by the container. */ - - resource_unload(resource); -} - -static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, - const struct wined3d_box *box) -{ - if (!box) - return TRUE; - - if (box->left >= box->right) - return FALSE; - if (box->top >= box->bottom) - return FALSE; - if (box->front >= box->back) - return FALSE; - if (box->right > volume->resource.width) - return FALSE; - if (box->bottom > volume->resource.height) - return FALSE; - if (box->back > volume->resource.depth) - return FALSE; - - return TRUE; -} - -HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ -#if defined(STAGING_CSMT) - HRESULT hr; - const struct wined3d_format *format = volume->resource.format; - const unsigned int fmt_flags = volume->container->resource.format_flags; - - map_desc->data = NULL; - if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - { - WARN("Volume %p is not CPU accessible.\n", volume); - return WINED3DERR_INVALIDCALL; - } - if (!wined3d_volume_check_box_dimensions(volume, box)) - { - WARN("Map box is invalid.\n"); - return WINED3DERR_INVALIDCALL; - } - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !wined3d_resource_check_block_align(&volume->resource, box)) - { - WARN("Map box %s is misaligned for %ux%u blocks.\n", - debug_box(box), format->block_width, format->block_height); - return WINED3DERR_INVALIDCALL; - } - - hr = wined3d_resource_map(&volume->resource, map_desc, box, flags); - if (FAILED(hr)) - return hr; - - return hr; -} - -HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) -{ - HRESULT hr; - - if (volume->resource.unmap_dirtify) - wined3d_texture_set_dirty(volume->container); - - hr = wined3d_resource_unmap(&volume->resource); - if (hr == WINEDDERR_NOTLOCKED) - return WINED3DERR_INVALIDCALL; - return hr; -#else /* STAGING_CSMT */ - struct wined3d_device *device = volume->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - BYTE *base_memory; - const struct wined3d_format *format = volume->resource.format; - const unsigned int fmt_flags = volume->container->resource.format_flags; - - TRACE("volume %p, map_desc %p, box %s, flags %#x.\n", - volume, map_desc, debug_box(box), flags); - - map_desc->data = NULL; - if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - { - WARN("Volume %p is not CPU accessible.\n", volume); - return WINED3DERR_INVALIDCALL; - } - if (volume->resource.map_count) - { - WARN("Volume is already mapped.\n"); - return WINED3DERR_INVALIDCALL; - } - if (!wined3d_volume_check_box_dimensions(volume, box)) - { - WARN("Map box is invalid.\n"); - return WINED3DERR_INVALIDCALL; - } - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !wined3d_texture_check_block_align(volume->container, volume->texture_level, box)) - { - WARN("Map box %s is misaligned for %ux%u blocks.\n", - debug_box(box), format->block_width, format->block_height); - return WINED3DERR_INVALIDCALL; - } - - flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); - - if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) - { - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - wined3d_volume_prepare_pbo(volume, context); - if (flags & WINED3D_MAP_DISCARD) - wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); - else - wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER); - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); - mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; - base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, - 0, volume->resource.size, mapflags)); - } - else - { - GLenum access = wined3d_resource_gl_legacy_map_flags(flags); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); - } - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Map PBO"); - - context_release(context); - } - else - { - if (!volume_prepare_system_memory(volume)) - { - WARN("Out of memory.\n"); - map_desc->data = NULL; - return E_OUTOFMEMORY; - } - - if (flags & WINED3D_MAP_DISCARD) - { - wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); - } - else if (!(volume->locations & WINED3D_LOCATION_SYSMEM)) - { - context = context_acquire(device, NULL); - wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); - context_release(context); - } - base_memory = volume->resource.heap_memory; - } - - TRACE("Base memory pointer %p.\n", base_memory); - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) - { - map_desc->row_pitch = volume->resource.width * format->byte_count; - map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; - } - else - { - wined3d_texture_get_pitch(volume->container, volume->texture_level, - &map_desc->row_pitch, &map_desc->slice_pitch); - } - - if (!box) - { - map_desc->data = base_memory; - } - else - { - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) - { - /* Compressed textures are block based, so calculate the offset of - * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = base_memory - + (box->front * map_desc->slice_pitch) - + ((box->top / format->block_height) * map_desc->row_pitch) - + ((box->left / format->block_width) * format->block_byte_count); - } - else - { - map_desc->data = base_memory - + (map_desc->slice_pitch * box->front) - + (map_desc->row_pitch * box->top) - + (box->left * volume->resource.format->byte_count); - } - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) - { - wined3d_texture_set_dirty(volume->container); - wined3d_volume_invalidate_location(volume, ~volume->resource.map_binding); - } - - volume->resource.map_count++; - - TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", - map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); - - return WINED3D_OK; -} - -HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) -{ - TRACE("volume %p.\n", volume); - - if (!volume->resource.map_count) - { - WARN("Trying to unlock an unlocked volume %p.\n", volume); - return WINED3DERR_INVALIDCALL; - } - - if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) - { - struct wined3d_device *device = volume->resource.device; - struct wined3d_context *context = context_acquire(device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Unmap PBO"); - - context_release(context); - } - - volume->resource.map_count--; - - return WINED3D_OK; -#endif /* STAGING_CSMT */ -} - -static ULONG volume_resource_incref(struct wined3d_resource *resource) -{ - struct wined3d_volume *volume = volume_from_resource(resource); - TRACE("Forwarding to container %p.\n", volume->container); - - return wined3d_texture_incref(volume->container); -} - -#if defined(STAGING_CSMT) -void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) -{ - HeapFree(GetProcessHeap(), 0, volume); -} - -#endif /* STAGING_CSMT */ -static ULONG volume_resource_decref(struct wined3d_resource *resource) -{ - struct wined3d_volume *volume = volume_from_resource(resource); - TRACE("Forwarding to container %p.\n", volume->container); - - return wined3d_texture_decref(volume->container); -} - -static HRESULT volume_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - ERR("Not supported on sub-resources.\n"); - return WINED3DERR_INVALIDCALL; -} - -static HRESULT volume_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -{ - ERR("Not supported on sub-resources.\n"); - return WINED3DERR_INVALIDCALL; -} - -#if defined(STAGING_CSMT) -static void wined3d_volume_location_invalidated(struct wined3d_resource *resource, DWORD location) -{ - struct wined3d_volume *volume = volume_from_resource(resource); - - if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - wined3d_texture_set_dirty(volume->container); -} - -#endif /* STAGING_CSMT */ -static const struct wined3d_resource_ops volume_resource_ops = -{ - volume_resource_incref, - volume_resource_decref, - volume_unload, - volume_resource_sub_resource_map, - volume_resource_sub_resource_unmap, -#if defined(STAGING_CSMT) - wined3d_volume_location_invalidated, - wined3d_volume_load_location, -#endif /* STAGING_CSMT */ -}; - -static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, - const struct wined3d_resource_desc *desc, UINT level) -{ - struct wined3d_device *device = container->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); - HRESULT hr; - UINT size; - - /* TODO: Write tests for other resources and move this check - * to resource_init, if applicable. */ - if (desc->usage & WINED3DUSAGE_DYNAMIC - && (desc->pool == WINED3D_POOL_MANAGED || desc->pool == WINED3D_POOL_SCRATCH)) - { - WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool)); - return WINED3DERR_INVALIDCALL; - } - - size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, desc->depth); - - if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format, - WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth, - size, NULL, &wined3d_null_parent_ops, &volume_resource_ops))) - { - WARN("Failed to initialize resource, returning %#x.\n", hr); - return hr; - } - - volume->texture_level = level; -#if defined(STAGING_CSMT) - volume->resource.locations = WINED3D_LOCATION_DISCARDED; -#else /* STAGING_CSMT */ - volume->locations = WINED3D_LOCATION_DISCARDED; -#endif /* STAGING_CSMT */ - - if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] - && !format->convert) - { - wined3d_resource_free_sysmem(&volume->resource); - volume->resource.map_binding = WINED3D_LOCATION_BUFFER; -#if defined(STAGING_CSMT) - volume->resource.map_heap_memory = NULL; -#endif /* STAGING_CSMT */ - } - - volume->container = container; - - return WINED3D_OK; -} - -HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - unsigned int level, struct wined3d_volume **volume) -{ - struct wined3d_device_parent *device_parent = container->resource.device->device_parent; - const struct wined3d_parent_ops *parent_ops; - struct wined3d_volume *object; - void *parent; - HRESULT hr; - - TRACE("container %p, width %u, height %u, depth %u, level %u, format %s, " - "usage %#x, pool %s, volume %p.\n", - container, desc->width, desc->height, desc->depth, level, debug_d3dformat(desc->format), - desc->usage, debug_d3dpool(desc->pool), volume); - - if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) - return E_OUTOFMEMORY; - - if (FAILED(hr = volume_init(object, container, desc, level))) - { - WARN("Failed to initialize volume, returning %#x.\n", hr); - HeapFree(GetProcessHeap(), 0, object); - return hr; - } - - if (FAILED(hr = device_parent->ops->volume_created(device_parent, - container, level, &parent, &parent_ops))) - { - WARN("Failed to create volume parent, hr %#x.\n", hr); - wined3d_volume_destroy(object); - return hr; - } - - TRACE("Created volume %p, parent %p, parent_ops %p.\n", object, parent, parent_ops); - - object->resource.parent = parent; - object->resource.parent_ops = parent_ops; - *volume = object; - - return WINED3D_OK; -} diff --git a/reactos/dll/directx/wine/wined3d/wined3d.spec b/reactos/dll/directx/wine/wined3d/wined3d.spec index f3cbd3deb28..8dc4fb432e9 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d.spec +++ b/reactos/dll/directx/wine/wined3d/wined3d.spec @@ -5,11 +5,13 @@ @ cdecl wined3d_check_depth_stencil_match(ptr long long long long long) @ cdecl wined3d_check_device_format(ptr long long long long long long) @ cdecl wined3d_check_device_format_conversion(ptr long long long long) +@ cdecl wined3d_check_device_format_support(ptr long ptr) @ cdecl wined3d_check_device_multisample_type(ptr long long long long long ptr) @ cdecl wined3d_check_device_type(ptr long long long long long) @ cdecl wined3d_create(long) @ cdecl wined3d_decref(ptr) @ cdecl wined3d_enum_adapter_modes(ptr long long long long ptr) +@ cdecl wined3d_find_closest_matching_adapter_mode(ptr long ptr) @ cdecl wined3d_get_adapter_count(ptr) @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr) @ cdecl wined3d_get_adapter_identifier(ptr long long ptr) @@ -28,19 +30,18 @@ @ cdecl wined3d_buffer_get_parent(ptr) @ cdecl wined3d_buffer_get_resource(ptr) @ cdecl wined3d_buffer_incref(ptr) -@ cdecl wined3d_buffer_map(ptr long long ptr long) -@ cdecl wined3d_buffer_preload(ptr) -@ cdecl wined3d_buffer_unmap(ptr) @ cdecl wined3d_device_acquire_focus_window(ptr ptr) @ cdecl wined3d_device_begin_scene(ptr) @ cdecl wined3d_device_begin_stateblock(ptr) @ cdecl wined3d_device_clear(ptr long ptr long ptr float long) -@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr ptr) +@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long) +@ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr) @ cdecl wined3d_device_copy_resource(ptr ptr ptr) @ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr) @ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr) @ cdecl wined3d_device_decref(ptr) +@ cdecl wined3d_device_dispatch_compute(ptr long long long) @ cdecl wined3d_device_draw_indexed_primitive(ptr long long) @ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long) @ cdecl wined3d_device_draw_primitive(ptr long long) @@ -52,30 +53,44 @@ @ cdecl wined3d_device_get_base_vertex_index(ptr) @ cdecl wined3d_device_get_clip_plane(ptr long ptr) @ cdecl wined3d_device_get_clip_status(ptr ptr) +@ cdecl wined3d_device_get_compute_shader(ptr) @ cdecl wined3d_device_get_creation_parameters(ptr ptr) +@ cdecl wined3d_device_get_cs_cb(ptr long) +@ cdecl wined3d_device_get_cs_resource_view(ptr long) +@ cdecl wined3d_device_get_cs_sampler(ptr long) +@ cdecl wined3d_device_get_cs_uav(ptr long) @ cdecl wined3d_device_get_depth_stencil_view(ptr) @ cdecl wined3d_device_get_device_caps(ptr ptr) @ cdecl wined3d_device_get_display_mode(ptr long ptr ptr) +@ cdecl wined3d_device_get_domain_shader(ptr) +@ cdecl wined3d_device_get_ds_cb(ptr long) +@ cdecl wined3d_device_get_ds_resource_view(ptr long) +@ cdecl wined3d_device_get_ds_sampler(ptr long) @ cdecl wined3d_device_get_gamma_ramp(ptr long ptr) @ cdecl wined3d_device_get_geometry_shader(ptr) @ cdecl wined3d_device_get_gs_cb(ptr long) @ cdecl wined3d_device_get_gs_resource_view(ptr long) @ cdecl wined3d_device_get_gs_sampler(ptr long) -@ cdecl wined3d_device_get_index_buffer(ptr ptr) +@ cdecl wined3d_device_get_hs_cb(ptr long) +@ cdecl wined3d_device_get_hs_resource_view(ptr long) +@ cdecl wined3d_device_get_hs_sampler(ptr long) +@ cdecl wined3d_device_get_hull_shader(ptr) +@ cdecl wined3d_device_get_index_buffer(ptr ptr ptr) @ cdecl wined3d_device_get_light(ptr long ptr) @ cdecl wined3d_device_get_light_enable(ptr long ptr) @ cdecl wined3d_device_get_material(ptr ptr) @ cdecl wined3d_device_get_npatch_mode(ptr) @ cdecl wined3d_device_get_pixel_shader(ptr) @ cdecl wined3d_device_get_predication(ptr ptr) -@ cdecl wined3d_device_get_primitive_type(ptr ptr) +@ cdecl wined3d_device_get_primitive_type(ptr ptr ptr) @ cdecl wined3d_device_get_ps_cb(ptr long) -@ cdecl wined3d_device_get_ps_consts_b(ptr long ptr long) -@ cdecl wined3d_device_get_ps_consts_f(ptr long ptr long) -@ cdecl wined3d_device_get_ps_consts_i(ptr long ptr long) +@ cdecl wined3d_device_get_ps_consts_b(ptr long long ptr) +@ cdecl wined3d_device_get_ps_consts_f(ptr long long ptr) +@ cdecl wined3d_device_get_ps_consts_i(ptr long long ptr) @ cdecl wined3d_device_get_ps_resource_view(ptr long) @ cdecl wined3d_device_get_ps_sampler(ptr long) @ cdecl wined3d_device_get_raster_status(ptr long ptr) +@ cdecl wined3d_device_get_rasterizer_state(ptr) @ cdecl wined3d_device_get_render_state(ptr long) @ cdecl wined3d_device_get_rendertarget_view(ptr long) @ cdecl wined3d_device_get_sampler_state(ptr long long) @@ -89,13 +104,14 @@ @ cdecl wined3d_device_get_texture(ptr long) @ cdecl wined3d_device_get_texture_stage_state(ptr long long) @ cdecl wined3d_device_get_transform(ptr long ptr) +@ cdecl wined3d_device_get_unordered_access_view(ptr long) @ cdecl wined3d_device_get_vertex_declaration(ptr) @ cdecl wined3d_device_get_vertex_shader(ptr) @ cdecl wined3d_device_get_viewport(ptr ptr) @ cdecl wined3d_device_get_vs_cb(ptr long) -@ cdecl wined3d_device_get_vs_consts_b(ptr long ptr long) -@ cdecl wined3d_device_get_vs_consts_f(ptr long ptr long) -@ cdecl wined3d_device_get_vs_consts_i(ptr long ptr long) +@ cdecl wined3d_device_get_vs_consts_b(ptr long long ptr) +@ cdecl wined3d_device_get_vs_consts_f(ptr long long ptr) +@ cdecl wined3d_device_get_vs_consts_i(ptr long long ptr) @ cdecl wined3d_device_get_vs_resource_view(ptr long) @ cdecl wined3d_device_get_vs_sampler(ptr long) @ cdecl wined3d_device_get_wined3d(ptr) @@ -106,20 +122,33 @@ @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long) @ cdecl wined3d_device_release_focus_window(ptr) @ cdecl wined3d_device_reset(ptr ptr ptr ptr long) -@ cdecl wined3d_device_restore_fullscreen_window(ptr ptr) +@ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr) @ cdecl wined3d_device_set_base_vertex_index(ptr long) @ cdecl wined3d_device_set_clip_plane(ptr long ptr) @ cdecl wined3d_device_set_clip_status(ptr ptr) +@ cdecl wined3d_device_set_compute_shader(ptr ptr) +@ cdecl wined3d_device_set_cs_cb(ptr long ptr) +@ cdecl wined3d_device_set_cs_resource_view(ptr long ptr) +@ cdecl wined3d_device_set_cs_sampler(ptr long ptr) +@ cdecl wined3d_device_set_cs_uav(ptr long ptr) @ cdecl wined3d_device_set_cursor_position(ptr long long long) @ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long) @ cdecl wined3d_device_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_set_dialog_box_mode(ptr long) +@ cdecl wined3d_device_set_domain_shader(ptr ptr) +@ cdecl wined3d_device_set_ds_cb(ptr long ptr) +@ cdecl wined3d_device_set_ds_resource_view(ptr long ptr) +@ cdecl wined3d_device_set_ds_sampler(ptr long ptr) @ cdecl wined3d_device_set_gamma_ramp(ptr long long ptr) @ cdecl wined3d_device_set_geometry_shader(ptr ptr) @ cdecl wined3d_device_set_gs_cb(ptr long ptr) @ cdecl wined3d_device_set_gs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_gs_sampler(ptr long ptr) -@ cdecl wined3d_device_set_index_buffer(ptr ptr long) +@ cdecl wined3d_device_set_hs_cb(ptr long ptr) +@ cdecl wined3d_device_set_hs_resource_view(ptr long ptr) +@ cdecl wined3d_device_set_hs_sampler(ptr long ptr) +@ cdecl wined3d_device_set_hull_shader(ptr ptr) +@ cdecl wined3d_device_set_index_buffer(ptr ptr long long) @ cdecl wined3d_device_set_light(ptr long ptr) @ cdecl wined3d_device_set_light_enable(ptr long long) @ cdecl wined3d_device_set_material(ptr ptr) @@ -127,13 +156,14 @@ @ cdecl wined3d_device_set_npatch_mode(ptr float) @ cdecl wined3d_device_set_pixel_shader(ptr ptr) @ cdecl wined3d_device_set_predication(ptr ptr long) -@ cdecl wined3d_device_set_primitive_type(ptr long) +@ cdecl wined3d_device_set_primitive_type(ptr long long) @ cdecl wined3d_device_set_ps_cb(ptr long ptr) -@ cdecl wined3d_device_set_ps_consts_b(ptr long ptr long) -@ cdecl wined3d_device_set_ps_consts_f(ptr long ptr long) -@ cdecl wined3d_device_set_ps_consts_i(ptr long ptr long) +@ cdecl wined3d_device_set_ps_consts_b(ptr long long ptr) +@ cdecl wined3d_device_set_ps_consts_f(ptr long long ptr) +@ cdecl wined3d_device_set_ps_consts_i(ptr long long ptr) @ cdecl wined3d_device_set_ps_resource_view(ptr long ptr) @ cdecl wined3d_device_set_ps_sampler(ptr long ptr) +@ cdecl wined3d_device_set_rasterizer_state(ptr ptr) @ cdecl wined3d_device_set_render_state(ptr long long) @ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long) @ cdecl wined3d_device_set_sampler_state(ptr long long long) @@ -145,13 +175,14 @@ @ cdecl wined3d_device_set_texture(ptr long ptr) @ cdecl wined3d_device_set_texture_stage_state(ptr long long long) @ cdecl wined3d_device_set_transform(ptr long ptr) +@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr) @ cdecl wined3d_device_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_set_vertex_shader(ptr ptr) @ cdecl wined3d_device_set_viewport(ptr ptr) @ cdecl wined3d_device_set_vs_cb(ptr long ptr) -@ cdecl wined3d_device_set_vs_consts_b(ptr long ptr long) -@ cdecl wined3d_device_set_vs_consts_f(ptr long ptr long) -@ cdecl wined3d_device_set_vs_consts_i(ptr long ptr long) +@ cdecl wined3d_device_set_vs_consts_b(ptr long long ptr) +@ cdecl wined3d_device_set_vs_consts_f(ptr long long ptr) +@ cdecl wined3d_device_set_vs_consts_i(ptr long long ptr) @ cdecl wined3d_device_set_vs_resource_view(ptr long ptr) @ cdecl wined3d_device_set_vs_sampler(ptr long ptr) @ cdecl wined3d_device_setup_fullscreen_window(ptr ptr long long) @@ -169,7 +200,7 @@ @ cdecl wined3d_palette_incref(ptr) @ cdecl wined3d_palette_set_entries(ptr long long long ptr) -@ cdecl wined3d_query_create(ptr long ptr ptr) +@ cdecl wined3d_query_create(ptr long ptr ptr ptr) @ cdecl wined3d_query_decref(ptr) @ cdecl wined3d_query_get_data(ptr ptr long long) @ cdecl wined3d_query_get_data_size(ptr) @@ -178,13 +209,20 @@ @ cdecl wined3d_query_incref(ptr) @ cdecl wined3d_query_issue(ptr long) +@ cdecl wined3d_rasterizer_state_create(ptr ptr ptr ptr ptr) +@ cdecl wined3d_rasterizer_state_decref(ptr) +@ cdecl wined3d_rasterizer_state_get_parent(ptr) +@ cdecl wined3d_rasterizer_state_incref(ptr) + @ cdecl wined3d_resource_get_desc(ptr ptr) @ cdecl wined3d_resource_get_parent(ptr) @ cdecl wined3d_resource_get_priority(ptr) +@ cdecl wined3d_resource_map(ptr long ptr ptr long) +@ cdecl wined3d_resource_map_info(ptr long ptr long) +@ cdecl wined3d_resource_preload(ptr) @ cdecl wined3d_resource_set_parent(ptr ptr) @ cdecl wined3d_resource_set_priority(ptr long) -@ cdecl wined3d_resource_sub_resource_map(ptr long ptr ptr long) -@ cdecl wined3d_resource_sub_resource_unmap(ptr long) +@ cdecl wined3d_resource_unmap(ptr long) @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr) @@ -195,12 +233,15 @@ @ cdecl wined3d_rendertarget_view_incref(ptr) @ cdecl wined3d_rendertarget_view_set_parent(ptr ptr) -@ cdecl wined3d_sampler_create(ptr ptr ptr ptr) +@ cdecl wined3d_sampler_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_sampler_decref(ptr) @ cdecl wined3d_sampler_get_parent(ptr) @ cdecl wined3d_sampler_incref(ptr) -@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr) +@ cdecl wined3d_shader_create_cs(ptr ptr ptr ptr ptr) +@ cdecl wined3d_shader_create_ds(ptr ptr ptr ptr ptr) +@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr ptr) +@ cdecl wined3d_shader_create_hs(ptr ptr ptr ptr ptr) @ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr) @ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr) @ cdecl wined3d_shader_decref(ptr) @@ -209,7 +250,7 @@ @ cdecl wined3d_shader_incref(ptr) @ cdecl wined3d_shader_set_local_constants_float(ptr long ptr long) -@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr ptr) +@ cdecl wined3d_shader_resource_view_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_shader_resource_view_decref(ptr) @ cdecl wined3d_shader_resource_view_get_parent(ptr) @ cdecl wined3d_shader_resource_view_incref(ptr) @@ -233,16 +274,19 @@ @ cdecl wined3d_swapchain_get_desc(ptr ptr) @ cdecl wined3d_swapchain_get_raster_status(ptr ptr) @ cdecl wined3d_swapchain_incref(ptr) -@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr ptr long) +@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long) @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long) +@ cdecl wined3d_swapchain_resize_target(ptr ptr) +@ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr) @ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr) @ cdecl wined3d_swapchain_set_palette(ptr ptr) @ cdecl wined3d_swapchain_set_window(ptr ptr) @ cdecl wined3d_texture_add_dirty_region(ptr long ptr) @ cdecl wined3d_texture_blt(ptr long ptr ptr long ptr long ptr long) -@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr ptr) +@ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr) @ cdecl wined3d_texture_decref(ptr) +@ cdecl wined3d_texture_from_resource(ptr) @ cdecl wined3d_texture_generate_mipmaps(ptr) @ cdecl wined3d_texture_get_autogen_filter_type(ptr) @ cdecl wined3d_texture_get_dc(ptr long ptr) @@ -252,18 +296,23 @@ @ cdecl wined3d_texture_get_parent(ptr) @ cdecl wined3d_texture_get_pitch(ptr long ptr ptr) @ cdecl wined3d_texture_get_resource(ptr) -@ cdecl wined3d_texture_get_sub_resource(ptr long) +@ cdecl wined3d_texture_get_sub_resource_desc(ptr long ptr) @ cdecl wined3d_texture_get_sub_resource_parent(ptr long) @ cdecl wined3d_texture_incref(ptr) -@ cdecl wined3d_texture_preload(ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr) @ cdecl wined3d_texture_set_autogen_filter_type(ptr long) @ cdecl wined3d_texture_set_color_key(ptr long ptr) @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) +@ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr) @ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long) @ cdecl wined3d_texture_update_overlay(ptr long ptr ptr long ptr long) +@ cdecl wined3d_unordered_access_view_create(ptr ptr ptr ptr ptr) +@ cdecl wined3d_unordered_access_view_decref(ptr) +@ cdecl wined3d_unordered_access_view_get_parent(ptr) +@ cdecl wined3d_unordered_access_view_incref(ptr) + @ cdecl wined3d_vertex_declaration_create(ptr ptr long ptr ptr ptr) @ cdecl wined3d_vertex_declaration_create_from_fvf(ptr long ptr ptr ptr) @ cdecl wined3d_vertex_declaration_decref(ptr) diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index 2903f3d425a..80fc6809238 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -44,19 +44,30 @@ enum wined3d_gl_extension APPLE_YCBCR_422, /* ARB */ ARB_BLEND_FUNC_EXTENDED, + ARB_CLEAR_BUFFER_OBJECT, + ARB_CLEAR_TEXTURE, + ARB_CLIP_CONTROL, ARB_COLOR_BUFFER_FLOAT, + ARB_COMPUTE_SHADER, + ARB_COPY_BUFFER, ARB_DEBUG_OUTPUT, ARB_DEPTH_BUFFER_FLOAT, ARB_DEPTH_TEXTURE, + ARB_DERIVATIVE_CONTROL, ARB_DRAW_BUFFERS, ARB_DRAW_ELEMENTS_BASE_VERTEX, ARB_DRAW_INSTANCED, ARB_ES2_COMPATIBILITY, + ARB_ES3_COMPATIBILITY, + ARB_EXPLICIT_ATTRIB_LOCATION, + ARB_FRAGMENT_COORD_CONVENTIONS, + ARB_FRAGMENT_LAYER_VIEWPORT, ARB_FRAGMENT_PROGRAM, ARB_FRAGMENT_SHADER, ARB_FRAMEBUFFER_OBJECT, ARB_FRAMEBUFFER_SRGB, ARB_GEOMETRY_SHADER4, + ARB_GPU_SHADER5, ARB_HALF_FLOAT_PIXEL, ARB_HALF_FLOAT_VERTEX, ARB_INSTANCED_ARRAYS, @@ -67,23 +78,38 @@ enum wined3d_gl_extension ARB_MULTISAMPLE, ARB_MULTITEXTURE, ARB_OCCLUSION_QUERY, + ARB_PIPELINE_STATISTICS_QUERY, ARB_PIXEL_BUFFER_OBJECT, ARB_POINT_PARAMETERS, ARB_POINT_SPRITE, ARB_PROVOKING_VERTEX, ARB_SAMPLER_OBJECTS, + ARB_SEAMLESS_CUBE_MAP, + ARB_SHADER_ATOMIC_COUNTERS, ARB_SHADER_BIT_ENCODING, + ARB_SHADER_IMAGE_LOAD_STORE, + ARB_SHADER_IMAGE_SIZE, + ARB_SHADER_STORAGE_BUFFER_OBJECT, ARB_SHADER_TEXTURE_LOD, ARB_SHADING_LANGUAGE_100, + ARB_SHADING_LANGUAGE_420PACK, + ARB_SHADING_LANGUAGE_PACKING, ARB_SHADOW, + ARB_STENCIL_TEXTURING, ARB_SYNC, + ARB_TESSELLATION_SHADER, ARB_TEXTURE_BORDER_CLAMP, + ARB_TEXTURE_BUFFER_OBJECT, + ARB_TEXTURE_BUFFER_RANGE, ARB_TEXTURE_COMPRESSION, + ARB_TEXTURE_COMPRESSION_BPTC, ARB_TEXTURE_COMPRESSION_RGTC, ARB_TEXTURE_CUBE_MAP, + ARB_TEXTURE_CUBE_MAP_ARRAY, ARB_TEXTURE_ENV_COMBINE, ARB_TEXTURE_ENV_DOT3, ARB_TEXTURE_FLOAT, + ARB_TEXTURE_GATHER, ARB_TEXTURE_MIRRORED_REPEAT, ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE, ARB_TEXTURE_NON_POWER_OF_TWO, @@ -91,13 +117,20 @@ enum wined3d_gl_extension ARB_TEXTURE_RECTANGLE, ARB_TEXTURE_RG, ARB_TEXTURE_RGB10_A2UI, + ARB_TEXTURE_STORAGE, + ARB_TEXTURE_SWIZZLE, + ARB_TEXTURE_VIEW, ARB_TIMER_QUERY, + ARB_TRANSFORM_FEEDBACK2, + ARB_TRANSFORM_FEEDBACK3, ARB_UNIFORM_BUFFER_OBJECT, ARB_VERTEX_ARRAY_BGRA, ARB_VERTEX_BLEND, ARB_VERTEX_BUFFER_OBJECT, ARB_VERTEX_PROGRAM, ARB_VERTEX_SHADER, + ARB_VERTEX_TYPE_2_10_10_10_REV, + ARB_VIEWPORT_ARRAY, /* ATI */ ATI_FRAGMENT_SHADER, ATI_SEPARATE_STENCIL, @@ -119,12 +152,14 @@ enum wined3d_gl_extension EXT_GPU_PROGRAM_PARAMETERS, EXT_GPU_SHADER4, EXT_PACKED_DEPTH_STENCIL, + EXT_PACKED_FLOAT, EXT_POINT_PARAMETERS, EXT_PROVOKING_VERTEX, EXT_SECONDARY_COLOR, EXT_STENCIL_TWO_SIDE, EXT_STENCIL_WRAP, EXT_TEXTURE3D, + EXT_TEXTURE_ARRAY, EXT_TEXTURE_COMPRESSION_RGTC, EXT_TEXTURE_COMPRESSION_S3TC, EXT_TEXTURE_ENV_COMBINE, @@ -133,6 +168,7 @@ enum wined3d_gl_extension EXT_TEXTURE_INTEGER, EXT_TEXTURE_LOD_BIAS, EXT_TEXTURE_MIRROR_CLAMP, + EXT_TEXTURE_SHARED_EXPONENT, EXT_TEXTURE_SNORM, EXT_TEXTURE_SRGB, EXT_TEXTURE_SRGB_DECODE, @@ -164,13 +200,16 @@ enum wined3d_gl_extension WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, WGL_WINE_PIXEL_FORMAT_PASSTHROUGH, - WGL_WINE_GPU_INFO, + WGL_WINE_QUERY_RENDERER, /* Internally used */ WINED3D_GL_BLEND_EQUATION, - WINED3D_GL_NORMALIZED_TEXRECT, WINED3D_GL_LEGACY_CONTEXT, + WINED3D_GL_NORMALIZED_TEXRECT, + WINED3D_GL_PRIMITIVE_QUERY, WINED3D_GL_VERSION_2_0, WINED3D_GL_VERSION_3_2, + WINED3D_GL_VERSION_4_3, + WINED3D_GLSL_130, WINED3D_GL_EXT_COUNT, }; diff --git a/reactos/dll/directx/wine/wined3d/wined3d_main.c b/reactos/dll/directx/wine/wined3d/wined3d_main.c index 34f99929c97..91cf61bdc17 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_main.c +++ b/reactos/dll/directx/wine/wined3d/wined3d_main.c @@ -41,7 +41,7 @@ struct wined3d_wndproc_table { struct wined3d_wndproc *entries; unsigned int count; - unsigned int size; + SIZE_T size; }; static struct wined3d_wndproc_table wndproc_table; @@ -70,6 +70,11 @@ static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0, * where appropriate. */ struct wined3d_settings wined3d_settings = { +#if !defined(STAGING_CSMT) + FALSE, /* No multithreaded CS by default. */ +#else /* STAGING_CSMT */ + TRUE, /* Multithreaded CS by default. */ +#endif /* STAGING_CSMT */ MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */ TRUE, /* Use of GLSL enabled by default */ ORM_FBO, /* Use FBOs to do offscreen rendering */ @@ -77,17 +82,16 @@ struct wined3d_settings wined3d_settings = PCI_DEVICE_NONE,/* PCI Device ID */ 0, /* The default of memory is set in init_driver_info */ NULL, /* No wine logo by default */ - TRUE, /* Multisampling enabled by default. */ + ~0u, /* Don't force a specific sample count by default. */ FALSE, /* No strict draw ordering. */ - TRUE, /* Don't try to render onscreen by default. */ + FALSE, /* Don't range check relative addressing indices in float constants. */ ~0U, /* No VS shader model limit by default. */ + ~0U, /* No HS shader model limit by default. */ + ~0U, /* No DS shader model limit by default. */ ~0U, /* No GS shader model limit by default. */ ~0U, /* No PS shader model limit by default. */ + ~0u, /* No CS shader model limit by default. */ FALSE, /* 3D support enabled by default. */ -#if defined(STAGING_CSMT) - TRUE, /* Multithreaded CS by default. */ - FALSE, /* Do not ignore render target maps. */ -#endif /* STAGING_CSMT */ }; struct wined3d * CDECL wined3d_create(DWORD flags) @@ -125,13 +129,20 @@ static DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, char *bu return ERROR_FILE_NOT_FOUND; } -static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *name, DWORD *data) +static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *name, DWORD *value) { - DWORD type; - DWORD size = sizeof(DWORD); - if (appkey && !RegQueryValueExA(appkey, name, 0, &type, (BYTE *)data, &size) && (type == REG_DWORD)) return 0; - if (defkey && !RegQueryValueExA(defkey, name, 0, &type, (BYTE *)data, &size) && (type == REG_DWORD)) return 0; + DWORD type, data, size; + + size = sizeof(data); + if (appkey && !RegQueryValueExA(appkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD) goto success; + size = sizeof(data); + if (defkey && !RegQueryValueExA(defkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD) goto success; + return ERROR_FILE_NOT_FOUND; + +success: + *value = data; + return 0; } static BOOL wined3d_dll_init(HINSTANCE hInstDLL) @@ -202,6 +213,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) if (hkey || appkey) { + if (!get_config_key_dword(hkey, appkey, "csmt", &wined3d_settings.cs_multithreaded)) + ERR_(winediag)("Setting multithreaded command stream to %#x.\n", wined3d_settings.cs_multithreaded); if (!get_config_key_dword(hkey, appkey, "MaxVersionGL", &tmpvalue)) { if (tmpvalue != wined3d_settings.max_gl_version) @@ -220,19 +233,9 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) wined3d_settings.glslRequested = FALSE; } } - if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) ) - { - if (!strcmp(buffer,"backbuffer")) - { - TRACE("Using the backbuffer for offscreen rendering\n"); - wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; - } - else if (!strcmp(buffer,"fbo")) - { - TRACE("Using FBOs for offscreen rendering\n"); - wined3d_settings.offscreen_rendering_mode = ORM_FBO; - } - } + if (!get_config_key(hkey, appkey, "OffscreenRenderingMode", buffer, size) + && !strcmp(buffer,"backbuffer")) + wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) ) { int pci_device_id = tmpvalue; @@ -284,59 +287,42 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) if (!wined3d_settings.logo) ERR("Failed to allocate logo path memory.\n"); else memcpy(wined3d_settings.logo, buffer, len); } - if ( !get_config_key( hkey, appkey, "Multisampling", buffer, size) ) - { - if (!strcmp(buffer, "disabled")) - { - TRACE("Multisampling disabled.\n"); - wined3d_settings.allow_multisampling = FALSE; - } - } + if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count)) + ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n", + wined3d_settings.sample_count); if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size) && !strcmp(buffer,"enabled")) { + ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead."); TRACE("Enforcing strict draw ordering.\n"); wined3d_settings.strict_draw_ordering = TRUE; } - if (!get_config_key(hkey, appkey, "AlwaysOffscreen", buffer, size) - && !strcmp(buffer,"disabled")) + if (!get_config_key(hkey, appkey, "CheckFloatConstants", buffer, size) + && !strcmp(buffer, "enabled")) { - TRACE("Not always rendering backbuffers offscreen.\n"); - wined3d_settings.always_offscreen = FALSE; + TRACE("Checking relative addressing indices in float constants.\n"); + wined3d_settings.check_float_constants = TRUE; } if (!get_config_key_dword(hkey, appkey, "MaxShaderModelVS", &wined3d_settings.max_sm_vs)) TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs); + if (!get_config_key_dword(hkey, appkey, "MaxShaderModelHS", &wined3d_settings.max_sm_hs)) + TRACE("Limiting HS shader model to %u.\n", wined3d_settings.max_sm_hs); + if (!get_config_key_dword(hkey, appkey, "MaxShaderModelDS", &wined3d_settings.max_sm_ds)) + TRACE("Limiting DS shader model to %u.\n", wined3d_settings.max_sm_ds); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelGS", &wined3d_settings.max_sm_gs)) TRACE("Limiting GS shader model to %u.\n", wined3d_settings.max_sm_gs); if (!get_config_key_dword(hkey, appkey, "MaxShaderModelPS", &wined3d_settings.max_sm_ps)) TRACE("Limiting PS shader model to %u.\n", wined3d_settings.max_sm_ps); + if (!get_config_key_dword(hkey, appkey, "MaxShaderModelCS", &wined3d_settings.max_sm_cs)) + TRACE("Limiting CS shader model to %u.\n", wined3d_settings.max_sm_cs); if (!get_config_key(hkey, appkey, "DirectDrawRenderer", buffer, size) && !strcmp(buffer, "gdi")) { TRACE("Disabling 3D support.\n"); wined3d_settings.no_3d = TRUE; } -#if defined(STAGING_CSMT) - if (!get_config_key(hkey, appkey, "CSMT", buffer, size) - && !strcmp(buffer,"disabled")) - { - TRACE("Disabling multithreaded command stream.\n"); - wined3d_settings.cs_multithreaded = FALSE; - } - if (!get_config_key(hkey, appkey, "ignore_rt_map", buffer, size) - && !strcmp(buffer,"enabled")) - { - TRACE("Ignoring render target maps.\n"); - wined3d_settings.ignore_rt_map = TRUE; - } } - FIXME_(winediag)("Experimental wined3d CSMT feature is currently %s.\n", - wined3d_settings.cs_multithreaded ? "enabled" : "disabled"); -#else /* STAGING_CSMT */ - } -#endif /* STAGING_CSMT */ - if (appkey) RegCloseKey( appkey ); if (hkey) RegCloseKey( hkey ); @@ -456,23 +442,12 @@ BOOL wined3d_register_window(HWND window, struct wined3d_device *device) return TRUE; } - if (wndproc_table.size == wndproc_table.count) + if (!wined3d_array_reserve((void **)&wndproc_table.entries, &wndproc_table.size, + wndproc_table.count + 1, sizeof(*entry))) { - unsigned int new_size = max(1, wndproc_table.size * 2); - struct wined3d_wndproc *new_entries; - - if (!wndproc_table.entries) new_entries = HeapAlloc(GetProcessHeap(), 0, new_size * sizeof(*new_entries)); - else new_entries = HeapReAlloc(GetProcessHeap(), 0, wndproc_table.entries, new_size * sizeof(*new_entries)); - - if (!new_entries) - { - wined3d_wndproc_mutex_unlock(); - ERR("Failed to grow table.\n"); - return FALSE; - } - - wndproc_table.entries = new_entries; - wndproc_table.size = new_size; + wined3d_wndproc_mutex_unlock(); + ERR("Failed to grow table.\n"); + return FALSE; } entry = &wndproc_table.entries[wndproc_table.count++]; diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 639dc70ca7d..5da23728105 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -1,28 +1,3 @@ -#if defined(STAGING_CSMT) -/* - * Direct3D wine internal private include file - * - * Copyright 2002-2003 The wine-d3d team - * Copyright 2002-2003 Raphael Junqueira - * Copyright 2002-2003, 2004 Jason Edmeades - * Copyright 2005 Oliver Stieber - * Copyright 2006-2011, 2013-2014 Stefan Dösinger for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -#else /* STAGING_CSMT */ /* * Direct3D wine internal private include file * @@ -46,7 +21,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#endif /* STAGING_CSMT */ #ifndef __WINE_WINED3D_PRIVATE_H #define __WINE_WINED3D_PRIVATE_H @@ -64,8 +38,10 @@ # include #endif +#include #include +#include #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H @@ -78,12 +54,15 @@ #include #include #include +#include +#include #include #include #include #include #include + #include "wined3d_gl.h" #include @@ -105,6 +84,49 @@ #define WINED3D_QUIRK_LIMITED_TEX_FILTERING 0x00000100 #define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200 +enum wined3d_ffp_idx +{ + WINED3D_FFP_POSITION = 0, + WINED3D_FFP_BLENDWEIGHT = 1, + WINED3D_FFP_BLENDINDICES = 2, + WINED3D_FFP_NORMAL = 3, + WINED3D_FFP_PSIZE = 4, + WINED3D_FFP_DIFFUSE = 5, + WINED3D_FFP_SPECULAR = 6, + WINED3D_FFP_TEXCOORD0 = 7, + WINED3D_FFP_TEXCOORD1 = 8, + WINED3D_FFP_TEXCOORD2 = 9, + WINED3D_FFP_TEXCOORD3 = 10, + WINED3D_FFP_TEXCOORD4 = 11, + WINED3D_FFP_TEXCOORD5 = 12, + WINED3D_FFP_TEXCOORD6 = 13, + WINED3D_FFP_TEXCOORD7 = 14, + WINED3D_FFP_ATTRIBS_COUNT = 15, +}; + +enum wined3d_ffp_emit_idx +{ + WINED3D_FFP_EMIT_FLOAT1, + WINED3D_FFP_EMIT_FLOAT2, + WINED3D_FFP_EMIT_FLOAT3, + WINED3D_FFP_EMIT_FLOAT4, + WINED3D_FFP_EMIT_D3DCOLOR, + WINED3D_FFP_EMIT_UBYTE4, + WINED3D_FFP_EMIT_SHORT2, + WINED3D_FFP_EMIT_SHORT4, + WINED3D_FFP_EMIT_UBYTE4N, + WINED3D_FFP_EMIT_SHORT2N, + WINED3D_FFP_EMIT_SHORT4N, + WINED3D_FFP_EMIT_USHORT2N, + WINED3D_FFP_EMIT_USHORT4N, + WINED3D_FFP_EMIT_UDEC3, + WINED3D_FFP_EMIT_DEC3N, + WINED3D_FFP_EMIT_FLOAT16_2, + WINED3D_FFP_EMIT_FLOAT16_4, + WINED3D_FFP_EMIT_INVALID, + WINED3D_FFP_EMIT_COUNT, +}; + /* Texture format fixups */ enum fixup_channel_source @@ -143,6 +165,47 @@ struct color_fixup_desc }; #include +struct wined3d_d3d_limits +{ + unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version; + DWORD vs_uniform_count; + DWORD ps_uniform_count; + unsigned int varying_count; + unsigned int ffp_textures; + unsigned int ffp_blend_stages; + unsigned int ffp_vertex_blend_matrices; + unsigned int active_light_count; +}; + +typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data); +typedef void (WINE_GLAPI *wined3d_ffp_texcoord_func)(GLenum unit, const void *data); +typedef void (WINE_GLAPI *wined3d_generic_attrib_func)(GLuint idx, const void *data); +extern wined3d_ffp_attrib_func specular_func_3ubv DECLSPEC_HIDDEN; + +struct wined3d_ffp_attrib_ops +{ + wined3d_ffp_attrib_func position[WINED3D_FFP_EMIT_COUNT]; + wined3d_ffp_attrib_func diffuse[WINED3D_FFP_EMIT_COUNT]; + wined3d_ffp_attrib_func specular[WINED3D_FFP_EMIT_COUNT]; + wined3d_ffp_attrib_func normal[WINED3D_FFP_EMIT_COUNT]; + wined3d_ffp_texcoord_func texcoord[WINED3D_FFP_EMIT_COUNT]; + wined3d_generic_attrib_func generic[WINED3D_FFP_EMIT_COUNT]; +}; + +struct wined3d_d3d_info +{ + struct wined3d_d3d_limits limits; + struct wined3d_ffp_attrib_ops ffp_attrib_ops; + BOOL xyzrhw; + BOOL emulated_flatshading; + BOOL ffp_generic_attributes; + BOOL vs_clipping; + BOOL shader_color_key; + DWORD valid_rt_mask; + DWORD wined3d_creation_flags; + BOOL shader_double_precision; +}; + static const struct color_fixup_desc COLOR_FIXUP_IDENTITY = {0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W}; @@ -205,22 +268,19 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup return complex_fixup; } -void *wined3d_rb_alloc(size_t size) DECLSPEC_HIDDEN; -void *wined3d_rb_realloc(void *ptr, size_t size) DECLSPEC_HIDDEN; -void wined3d_rb_free(void *ptr) DECLSPEC_HIDDEN; - /* Device caps */ -#define MAX_STREAM_OUT 4 #define MAX_STREAMS 16 #define MAX_TEXTURES 8 #define MAX_FRAGMENT_SAMPLERS 16 #define MAX_VERTEX_SAMPLERS 4 #define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS) #define MAX_ACTIVE_LIGHTS 8 -#define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES +#define MAX_CLIP_DISTANCES WINED3DMAXUSERCLIPPLANES #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 +#define MAX_UNORDERED_ACCESS_VIEWS 8 +#define MAX_TGSM_REGISTERS 8192 #define MAX_VERTEX_BLENDS 4 #define MAX_MULTISAMPLE_TYPES 8 @@ -234,6 +294,13 @@ extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN; GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN; +static inline enum wined3d_cmp_func wined3d_sanitize_cmp_func(enum wined3d_cmp_func func) +{ + if (func < WINED3D_CMP_NEVER || func > WINED3D_CMP_ALWAYS) + return WINED3D_CMP_ALWAYS; + return func; +} + static inline GLenum wined3d_gl_mag_filter(enum wined3d_texture_filter_type mag_filter) { return magLookup[mag_filter]; @@ -306,6 +373,13 @@ static inline unsigned int wined3d_popcount(unsigned int x) #endif } +static inline void wined3d_pause(void) +{ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ __volatile__( "rep;nop" : : : "memory" ); +#endif +} + #define ORM_BACKBUFFER 0 #define ORM_FBO 1 @@ -316,6 +390,7 @@ static inline unsigned int wined3d_popcount(unsigned int x) * values in wined3d_main.c as well. */ struct wined3d_settings { + unsigned int cs_multithreaded; DWORD max_gl_version; BOOL glslRequested; int offscreen_rendering_mode; @@ -324,17 +399,16 @@ struct wined3d_settings /* Memory tracking and object counting. */ UINT64 emulated_textureram; char *logo; - int allow_multisampling; + unsigned int sample_count; BOOL strict_draw_ordering; - BOOL always_offscreen; + BOOL check_float_constants; unsigned int max_sm_vs; + unsigned int max_sm_hs; + unsigned int max_sm_ds; unsigned int max_sm_gs; unsigned int max_sm_ps; + unsigned int max_sm_cs; BOOL no_3d; -#if defined(STAGING_CSMT) - BOOL cs_multithreaded; - BOOL ignore_rt_map; -#endif /* STAGING_CSMT */ }; extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; @@ -351,28 +425,31 @@ enum wined3d_shader_resource_type WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY, WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY, WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY, + WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY, }; #define WINED3D_SHADER_CONST_VS_F 0x00000001 #define WINED3D_SHADER_CONST_VS_I 0x00000002 #define WINED3D_SHADER_CONST_VS_B 0x00000004 -#define WINED3D_SHADER_CONST_VS_POINTSIZE 0x00000008 -#define WINED3D_SHADER_CONST_VS_POS_FIXUP 0x00000010 -#define WINED3D_SHADER_CONST_PS_F 0x00000020 -#define WINED3D_SHADER_CONST_PS_I 0x00000040 -#define WINED3D_SHADER_CONST_PS_B 0x00000080 -#define WINED3D_SHADER_CONST_PS_BUMP_ENV 0x00000100 -#define WINED3D_SHADER_CONST_PS_FOG 0x00000200 -#define WINED3D_SHADER_CONST_PS_Y_CORR 0x00000400 -#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00000800 -#define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00001000 -#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0x00002000 -#define WINED3D_SHADER_CONST_FFP_PROJ 0x00004000 -#define WINED3D_SHADER_CONST_FFP_TEXMATRIX 0x00008000 -#define WINED3D_SHADER_CONST_FFP_MATERIAL 0x00010000 -#define WINED3D_SHADER_CONST_FFP_LIGHTS 0x00020000 -#define WINED3D_SHADER_CONST_FFP_PS 0x00040000 -#define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00080000 +#define WINED3D_SHADER_CONST_VS_CLIP_PLANES 0x00000008 +#define WINED3D_SHADER_CONST_VS_POINTSIZE 0x00000010 +#define WINED3D_SHADER_CONST_POS_FIXUP 0x00000020 +#define WINED3D_SHADER_CONST_PS_F 0x00000040 +#define WINED3D_SHADER_CONST_PS_I 0x00000080 +#define WINED3D_SHADER_CONST_PS_B 0x00000100 +#define WINED3D_SHADER_CONST_PS_BUMP_ENV 0x00000200 +#define WINED3D_SHADER_CONST_PS_FOG 0x00000400 +#define WINED3D_SHADER_CONST_PS_ALPHA_TEST 0x00000800 +#define WINED3D_SHADER_CONST_PS_Y_CORR 0x00001000 +#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00002000 +#define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00004000 +#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0x00008000 +#define WINED3D_SHADER_CONST_FFP_PROJ 0x00010000 +#define WINED3D_SHADER_CONST_FFP_TEXMATRIX 0x00020000 +#define WINED3D_SHADER_CONST_FFP_MATERIAL 0x00040000 +#define WINED3D_SHADER_CONST_FFP_LIGHTS 0x00080000 +#define WINED3D_SHADER_CONST_FFP_PS 0x00100000 +#define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00200000 enum wined3d_shader_register_type { @@ -404,6 +481,26 @@ enum wined3d_shader_register_type WINED3DSPR_PRIMID, WINED3DSPR_NULL, WINED3DSPR_RESOURCE, + WINED3DSPR_UAV, + WINED3DSPR_OUTPOINTID, + WINED3DSPR_FORKINSTID, + WINED3DSPR_JOININSTID, + WINED3DSPR_INCONTROLPOINT, + WINED3DSPR_OUTCONTROLPOINT, + WINED3DSPR_PATCHCONST, + WINED3DSPR_TESSCOORD, + WINED3DSPR_GROUPSHAREDMEM, + WINED3DSPR_THREADID, + WINED3DSPR_THREADGROUPID, + WINED3DSPR_LOCALTHREADID, + WINED3DSPR_LOCALTHREADINDEX, + WINED3DSPR_IDXTEMP, + WINED3DSPR_STREAM, + WINED3DSPR_FUNCTIONBODY, + WINED3DSPR_FUNCTIONPOINTER, + WINED3DSPR_COVERAGE, + WINED3DSPR_SAMPLEMASK, + WINED3DSPR_GSINSTID, }; enum wined3d_data_type @@ -412,9 +509,11 @@ enum wined3d_data_type WINED3D_DATA_INT, WINED3D_DATA_RESOURCE, WINED3D_DATA_SAMPLER, + WINED3D_DATA_UAV, WINED3D_DATA_UINT, WINED3D_DATA_UNORM, WINED3D_DATA_SNORM, + WINED3D_DATA_OPAQUE, }; enum wined3d_immconst_type @@ -474,12 +573,48 @@ enum wined3d_shader_global_flags WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x8, }; +enum wined3d_shader_sync_flags +{ + WINED3DSSF_THREAD_GROUP = 0x1, + WINED3DSSF_GROUP_SHARED_MEMORY = 0x2, +}; + +enum wined3d_shader_uav_flags +{ + WINED3DSUF_GLOBALLY_COHERENT = 0x2, + WINED3DSUF_ORDER_PRESERVING_COUNTER = 0x100, +}; + +enum wined3d_tessellator_domain +{ + WINED3D_TESSELLATOR_DOMAIN_LINE = 1, + WINED3D_TESSELLATOR_DOMAIN_TRIANGLE = 2, + WINED3D_TESSELLATOR_DOMAIN_QUAD = 3, +}; + +enum wined3d_tessellator_output_primitive +{ + WINED3D_TESSELLATOR_OUTPUT_POINT = 1, + WINED3D_TESSELLATOR_OUTPUT_LINE = 2, + WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, + WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4, +}; + +enum wined3d_tessellator_partitioning +{ + WINED3D_TESSELLATOR_PARTITIONING_INTEGER = 1, + WINED3D_TESSELLATOR_PARTITIONING_POW2 = 2, + WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, + WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4, +}; + /* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */ #define WINED3DSI_TEXLD_PROJECT 0x1 #define WINED3DSI_TEXLD_BIAS 0x2 #define WINED3DSI_INDEXED_DYNAMIC 0x4 #define WINED3DSI_RESINFO_RCP_FLOAT 0x1 #define WINED3DSI_RESINFO_UINT 0x2 +#define WINED3DSI_SAMPLE_INFO_UINT 0x1 #define WINED3DSI_SAMPLER_COMPARISON_MODE 0x1 enum wined3d_shader_rel_op @@ -492,11 +627,20 @@ enum wined3d_shader_rel_op WINED3D_SHADER_REL_OP_LE = 6, }; +enum wined3d_shader_conditional_op +{ + WINED3D_SHADER_CONDITIONAL_OP_NZ = 0, + WINED3D_SHADER_CONDITIONAL_OP_Z = 1 +}; + #define WINED3D_SM1_VS 0xfffeu #define WINED3D_SM1_PS 0xffffu #define WINED3D_SM4_PS 0x0000u #define WINED3D_SM4_VS 0x0001u #define WINED3D_SM4_GS 0x0002u +#define WINED3D_SM5_HS 0x0003u +#define WINED3D_SM5_DS 0x0004u +#define WINED3D_SM5_CS 0x0005u /* Shader version tokens, and shader end tokens */ #define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor)) @@ -507,13 +651,14 @@ enum wined3d_shader_rel_op /* TODO: Make this dynamic, based on shader limits ? */ #define MAX_ATTRIBS 16 #define MAX_REG_ADDR 1 -#define MAX_REG_TEMP 32 #define MAX_REG_TEXCRD 8 #define MAX_REG_INPUT 32 #define MAX_REG_OUTPUT 32 -#define MAX_CONST_I 16 -#define MAX_CONST_B 16 #define WINED3D_MAX_CBS 15 +#define WINED3D_MAX_CONSTS_B 16 +#define WINED3D_MAX_CONSTS_I 16 +#define WINED3D_MAX_VS_CONSTS_F 256 +#define WINED3D_MAX_PS_CONSTS_F 224 /* FIXME: This needs to go up to 2048 for * Shader model 3 according to msdn (and for software shaders) */ @@ -534,34 +679,75 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_ABS, WINED3DSIH_ADD, WINED3DSIH_AND, + WINED3DSIH_ATOMIC_AND, + WINED3DSIH_ATOMIC_CMP_STORE, + WINED3DSIH_ATOMIC_IADD, + WINED3DSIH_ATOMIC_IMAX, + WINED3DSIH_ATOMIC_IMIN, + WINED3DSIH_ATOMIC_OR, + WINED3DSIH_ATOMIC_UMAX, + WINED3DSIH_ATOMIC_UMIN, + WINED3DSIH_ATOMIC_XOR, WINED3DSIH_BEM, + WINED3DSIH_BFI, + WINED3DSIH_BFREV, WINED3DSIH_BREAK, WINED3DSIH_BREAKC, WINED3DSIH_BREAKP, + WINED3DSIH_BUFINFO, WINED3DSIH_CALL, WINED3DSIH_CALLNZ, + WINED3DSIH_CASE, WINED3DSIH_CMP, WINED3DSIH_CND, + WINED3DSIH_CONTINUE, + WINED3DSIH_CONTINUEP, + WINED3DSIH_COUNTBITS, WINED3DSIH_CRS, WINED3DSIH_CUT, + WINED3DSIH_CUT_STREAM, WINED3DSIH_DCL, WINED3DSIH_DCL_CONSTANT_BUFFER, + WINED3DSIH_DCL_FUNCTION_BODY, + WINED3DSIH_DCL_FUNCTION_TABLE, WINED3DSIH_DCL_GLOBAL_FLAGS, + WINED3DSIH_DCL_GS_INSTANCES, + WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, + WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, + WINED3DSIH_DCL_HS_MAX_TESSFACTOR, WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, + WINED3DSIH_DCL_INDEX_RANGE, + WINED3DSIH_DCL_INDEXABLE_TEMP, WINED3DSIH_DCL_INPUT, + WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, WINED3DSIH_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PS, WINED3DSIH_DCL_INPUT_PS_SGV, WINED3DSIH_DCL_INPUT_PS_SIV, WINED3DSIH_DCL_INPUT_SGV, WINED3DSIH_DCL_INPUT_SIV, + WINED3DSIH_DCL_INTERFACE, WINED3DSIH_DCL_OUTPUT, + WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, WINED3DSIH_DCL_OUTPUT_SIV, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, + WINED3DSIH_DCL_RESOURCE_RAW, + WINED3DSIH_DCL_RESOURCE_STRUCTURED, WINED3DSIH_DCL_SAMPLER, + WINED3DSIH_DCL_STREAM, WINED3DSIH_DCL_TEMPS, + WINED3DSIH_DCL_TESSELLATOR_DOMAIN, + WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, + WINED3DSIH_DCL_TESSELLATOR_PARTITIONING, + WINED3DSIH_DCL_TGSM_RAW, + WINED3DSIH_DCL_TGSM_STRUCTURED, + WINED3DSIH_DCL_THREAD_GROUP, + WINED3DSIH_DCL_UAV_RAW, + WINED3DSIH_DCL_UAV_STRUCTURED, + WINED3DSIH_DCL_UAV_TYPED, WINED3DSIH_DCL_VERTICES_OUT, WINED3DSIH_DEF, + WINED3DSIH_DEFAULT, WINED3DSIH_DEFB, WINED3DSIH_DEFI, WINED3DSIH_DIV, @@ -571,20 +757,41 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_DP4, WINED3DSIH_DST, WINED3DSIH_DSX, + WINED3DSIH_DSX_COARSE, + WINED3DSIH_DSX_FINE, WINED3DSIH_DSY, + WINED3DSIH_DSY_COARSE, + WINED3DSIH_DSY_FINE, WINED3DSIH_ELSE, WINED3DSIH_EMIT, + WINED3DSIH_EMIT_STREAM, WINED3DSIH_ENDIF, WINED3DSIH_ENDLOOP, WINED3DSIH_ENDREP, + WINED3DSIH_ENDSWITCH, WINED3DSIH_EQ, WINED3DSIH_EXP, WINED3DSIH_EXPP, + WINED3DSIH_F16TOF32, + WINED3DSIH_F32TOF16, + WINED3DSIH_FCALL, + WINED3DSIH_FIRSTBIT_HI, + WINED3DSIH_FIRSTBIT_LO, + WINED3DSIH_FIRSTBIT_SHI, WINED3DSIH_FRC, WINED3DSIH_FTOI, WINED3DSIH_FTOU, + WINED3DSIH_GATHER4, + WINED3DSIH_GATHER4_C, + WINED3DSIH_GATHER4_PO, + WINED3DSIH_GATHER4_PO_C, WINED3DSIH_GE, + WINED3DSIH_HS_CONTROL_POINT_PHASE, + WINED3DSIH_HS_DECLS, + WINED3DSIH_HS_FORK_PHASE, + WINED3DSIH_HS_JOIN_PHASE, WINED3DSIH_IADD, + WINED3DSIH_IBFE, WINED3DSIH_IEQ, WINED3DSIH_IF, WINED3DSIH_IFC, @@ -593,14 +800,32 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_IMAD, WINED3DSIH_IMAX, WINED3DSIH_IMIN, + WINED3DSIH_IMM_ATOMIC_ALLOC, + WINED3DSIH_IMM_ATOMIC_AND, + WINED3DSIH_IMM_ATOMIC_CMP_EXCH, + WINED3DSIH_IMM_ATOMIC_CONSUME, + WINED3DSIH_IMM_ATOMIC_EXCH, + WINED3DSIH_IMM_ATOMIC_IADD, + WINED3DSIH_IMM_ATOMIC_IMAX, + WINED3DSIH_IMM_ATOMIC_IMIN, + WINED3DSIH_IMM_ATOMIC_OR, + WINED3DSIH_IMM_ATOMIC_UMAX, + WINED3DSIH_IMM_ATOMIC_UMIN, + WINED3DSIH_IMM_ATOMIC_XOR, WINED3DSIH_IMUL, WINED3DSIH_INE, WINED3DSIH_INEG, WINED3DSIH_ISHL, + WINED3DSIH_ISHR, WINED3DSIH_ITOF, WINED3DSIH_LABEL, WINED3DSIH_LD, + WINED3DSIH_LD2DMS, + WINED3DSIH_LD_RAW, + WINED3DSIH_LD_STRUCTURED, + WINED3DSIH_LD_UAV_TYPED, WINED3DSIH_LIT, + WINED3DSIH_LOD, WINED3DSIH_LOG, WINED3DSIH_LOGP, WINED3DSIH_LOOP, @@ -629,6 +854,8 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_REP, WINED3DSIH_RESINFO, WINED3DSIH_RET, + WINED3DSIH_RETP, + WINED3DSIH_ROUND_NE, WINED3DSIH_ROUND_NI, WINED3DSIH_ROUND_PI, WINED3DSIH_ROUND_Z, @@ -638,14 +865,22 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_SAMPLE_C, WINED3DSIH_SAMPLE_C_LZ, WINED3DSIH_SAMPLE_GRAD, + WINED3DSIH_SAMPLE_INFO, WINED3DSIH_SAMPLE_LOD, + WINED3DSIH_SAMPLE_POS, WINED3DSIH_SETP, WINED3DSIH_SGE, WINED3DSIH_SGN, WINED3DSIH_SINCOS, WINED3DSIH_SLT, WINED3DSIH_SQRT, + WINED3DSIH_STORE_RAW, + WINED3DSIH_STORE_STRUCTURED, + WINED3DSIH_STORE_UAV_TYPED, WINED3DSIH_SUB, + WINED3DSIH_SWAPC, + WINED3DSIH_SWITCH, + WINED3DSIH_SYNC, WINED3DSIH_TEX, WINED3DSIH_TEXBEM, WINED3DSIH_TEXBEML, @@ -668,8 +903,13 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_TEXREG2AR, WINED3DSIH_TEXREG2GB, WINED3DSIH_TEXREG2RGB, + WINED3DSIH_UBFE, WINED3DSIH_UDIV, WINED3DSIH_UGE, + WINED3DSIH_ULT, + WINED3DSIH_UMAX, + WINED3DSIH_UMIN, + WINED3DSIH_UMUL, WINED3DSIH_USHR, WINED3DSIH_UTOF, WINED3DSIH_XOR, @@ -681,6 +921,11 @@ enum wined3d_shader_type WINED3D_SHADER_TYPE_PIXEL, WINED3D_SHADER_TYPE_VERTEX, WINED3D_SHADER_TYPE_GEOMETRY, + WINED3D_SHADER_TYPE_HULL, + WINED3D_SHADER_TYPE_DOMAIN, + WINED3D_SHADER_TYPE_GRAPHICS_COUNT, + + WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT, WINED3D_SHADER_TYPE_COUNT, }; @@ -695,6 +940,8 @@ struct wined3d_shader_resource_info { enum wined3d_shader_resource_type type; enum wined3d_data_type data_type; + unsigned int flags; + unsigned int stride; }; #define WINED3D_SAMPLER_DEFAULT ~0x0u @@ -715,10 +962,18 @@ struct wined3d_shader_sampler_map struct wined3d_shader_immediate_constant_buffer { - UINT element_count; + unsigned int vec4_count; DWORD data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE]; }; +struct wined3d_shader_indexable_temp +{ + struct list entry; + unsigned int register_idx; + unsigned int register_size; + unsigned int component_count; +}; + #define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor)) struct wined3d_shader_reg_maps @@ -727,8 +982,10 @@ struct wined3d_shader_reg_maps BYTE texcoord; /* MAX_REG_TEXCRD, 8 */ BYTE address; /* MAX_REG_ADDR, 1 */ WORD labels; /* MAX_LABELS, 16 */ - DWORD temporary; /* MAX_REG_TEMP, 32 */ + DWORD temporary; /* 32 */ + unsigned int temporary_count; DWORD *constf; /* pixel, vertex */ + struct list indexable_temps; const struct wined3d_shader_immediate_constant_buffer *icb; union { @@ -737,16 +994,20 @@ struct wined3d_shader_reg_maps } u; DWORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 32 */ DWORD output_registers; /* MAX_REG_OUTPUT, 32 */ - WORD integer_constants; /* MAX_CONST_I, 16 */ - WORD boolean_constants; /* MAX_CONST_B, 16 */ - WORD local_int_consts; /* MAX_CONST_I, 16 */ - WORD local_bool_consts; /* MAX_CONST_B, 16 */ + WORD integer_constants; /* WINED3D_MAX_CONSTS_I, 16 */ + WORD boolean_constants; /* WINED3D_MAX_CONSTS_B, 16 */ + WORD local_int_consts; /* WINED3D_MAX_CONSTS_I, 16 */ + WORD local_bool_consts; /* WINED3D_MAX_CONSTS_B, 16 */ UINT cb_sizes[WINED3D_MAX_CBS]; - struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; + struct wined3d_shader_resource_info resource_info[MAX_SHADER_RESOURCE_VIEWS]; struct wined3d_shader_sampler_map sampler_map; + DWORD sampler_comparison_mode; BYTE bumpmat; /* MAX_TEXTURES, 8 */ BYTE luminanceparams; /* MAX_TEXTURES, 8 */ + struct wined3d_shader_resource_info uav_resource_info[MAX_UNORDERED_ACCESS_VIEWS]; + DWORD uav_read_mask; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ + DWORD uav_counter_mask; /* MAX_UNORDERED_ACCESS_VIEWS, 8 */ WORD usesnrm : 1; WORD vpos : 1; @@ -762,13 +1023,18 @@ struct wined3d_shader_reg_maps WORD usescall : 1; WORD usespow : 1; WORD point_size : 1; - WORD padding : 2; + WORD vocp : 1; + WORD padding : 1; DWORD rt_mask; /* Used render targets, 32 max. */ /* Whether or not loops are used in this shader, and nesting depth */ unsigned loop_depth; UINT min_rel_offset, max_rel_offset; + + struct wined3d_shader_tgsm *tgsm; + SIZE_T tgsm_capacity; + unsigned int tgsm_count; }; /* Keeps track of details for TEX_M#x# instructions which need to maintain @@ -779,10 +1045,11 @@ struct wined3d_shader_tex_mx DWORD texcoord_w[2]; }; -struct wined3d_shader_loop_state +struct wined3d_shader_parser_state { - UINT current_depth; - UINT current_reg; + unsigned int current_loop_depth; + unsigned int current_loop_reg; + BOOL in_subroutine; }; struct wined3d_shader_context @@ -792,7 +1059,7 @@ struct wined3d_shader_context const struct wined3d_shader_reg_maps *reg_maps; struct wined3d_string_buffer *buffer; struct wined3d_shader_tex_mx *tex_mx; - struct wined3d_shader_loop_state *loop_state; + struct wined3d_shader_parser_state *state; void *backend_data; }; @@ -808,7 +1075,11 @@ struct wined3d_shader_register enum wined3d_data_type data_type; struct wined3d_shader_register_index idx[2]; enum wined3d_immconst_type immconst_type; - DWORD immconst_data[4]; + union + { + DWORD immconst_data[4]; + unsigned fp_body_idx; + } u; }; struct wined3d_shader_dst_param @@ -826,6 +1097,12 @@ struct wined3d_shader_src_param enum wined3d_shader_src_modifier modifiers; }; +struct wined3d_shader_index_range +{ + struct wined3d_shader_dst_param first_register; + unsigned int last_register; +}; + struct wined3d_shader_semantic { enum wined3d_decl_usage usage; @@ -835,10 +1112,85 @@ struct wined3d_shader_semantic struct wined3d_shader_dst_param reg; }; +enum wined3d_shader_input_sysval_semantic +{ + WINED3D_SIV_POSITION = 1, + WINED3D_SIV_CLIP_DISTANCE = 2, + WINED3D_SIV_CULL_DISTANCE = 3, + WINED3D_SIV_RENDER_TARGET_ARRAY_INDEX = 4, + WINED3D_SIV_VIEWPORT_ARRAY_INDEX = 5, + WINED3D_SIV_VERTEX_ID = 6, + WINED3D_SIV_PRIMITIVE_ID = 7, + WINED3D_SIV_INSTANCE_ID = 8, + WINED3D_SIV_IS_FRONT_FACE = 9, + WINED3D_SIV_SAMPLE_INDEX = 10, + WINED3D_SIV_QUAD_U0_TESS_FACTOR = 11, + WINED3D_SIV_QUAD_V0_TESS_FACTOR = 12, + WINED3D_SIV_QUAD_U1_TESS_FACTOR = 13, + WINED3D_SIV_QUAD_V1_TESS_FACTOR = 14, + WINED3D_SIV_QUAD_U_INNER_TESS_FACTOR = 15, + WINED3D_SIV_QUAD_V_INNER_TESS_FACTOR = 16, + WINED3D_SIV_TRIANGLE_U_TESS_FACTOR = 17, + WINED3D_SIV_TRIANGLE_V_TESS_FACTOR = 18, + WINED3D_SIV_TRIANGLE_W_TESS_FACTOR = 19, + WINED3D_SIV_TRIANGLE_INNER_TESS_FACTOR = 20, + WINED3D_SIV_LINE_DETAIL_TESS_FACTOR = 21, + WINED3D_SIV_LINE_DENSITY_TESS_FACTOR = 22, +}; + struct wined3d_shader_register_semantic { struct wined3d_shader_dst_param reg; - enum wined3d_sysval_semantic sysval_semantic; + enum wined3d_shader_input_sysval_semantic sysval_semantic; +}; + +struct wined3d_shader_structured_resource +{ + struct wined3d_shader_dst_param reg; + unsigned int byte_stride; +}; + +struct wined3d_shader_tgsm +{ + unsigned int size; + unsigned int stride; +}; + +struct wined3d_shader_tgsm_raw +{ + struct wined3d_shader_dst_param reg; + unsigned int byte_count; +}; + +struct wined3d_shader_tgsm_structured +{ + struct wined3d_shader_dst_param reg; + unsigned int byte_stride; + unsigned int structure_count; +}; + +struct wined3d_shader_thread_group_size +{ + unsigned int x, y, z; +}; + +struct wined3d_shader_function_table_pointer +{ + unsigned int index; + unsigned int array_size; + unsigned int body_count; + unsigned int table_count; +}; + +struct wined3d_shader_texel_offset +{ + signed char u, v, w; +}; + +struct wined3d_shader_primitive_type +{ + enum wined3d_primitive_type type; + unsigned int patch_vertex_count; }; struct wined3d_shader_instruction @@ -846,24 +1198,42 @@ struct wined3d_shader_instruction const struct wined3d_shader_context *ctx; enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; DWORD flags; + unsigned int dst_count; + unsigned int src_count; + const struct wined3d_shader_dst_param *dst; + const struct wined3d_shader_src_param *src; + struct wined3d_shader_texel_offset texel_offset; BOOL coissue; const struct wined3d_shader_src_param *predicate; - UINT dst_count; - const struct wined3d_shader_dst_param *dst; - UINT src_count; - const struct wined3d_shader_src_param *src; union { struct wined3d_shader_semantic semantic; struct wined3d_shader_register_semantic register_semantic; - enum wined3d_primitive_type primitive_type; + struct wined3d_shader_primitive_type primitive_type; struct wined3d_shader_dst_param dst; struct wined3d_shader_src_param src; - UINT count; + unsigned int count; + unsigned int index; const struct wined3d_shader_immediate_constant_buffer *icb; + struct wined3d_shader_structured_resource structured_resource; + struct wined3d_shader_tgsm_raw tgsm_raw; + struct wined3d_shader_tgsm_structured tgsm_structured; + struct wined3d_shader_thread_group_size thread_group_size; + enum wined3d_tessellator_domain tessellator_domain; + enum wined3d_tessellator_output_primitive tessellator_output_primitive; + enum wined3d_tessellator_partitioning tessellator_partitioning; + float max_tessellation_factor; + struct wined3d_shader_index_range index_range; + struct wined3d_shader_indexable_temp indexable_temp; + struct wined3d_shader_function_table_pointer fp; } declaration; }; +static inline BOOL wined3d_shader_instruction_has_texel_offset(const struct wined3d_shader_instruction *ins) +{ + return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w; +} + struct wined3d_shader_attribute { enum wined3d_decl_usage usage; @@ -879,7 +1249,8 @@ struct wined3d_shader_loop_control struct wined3d_shader_frontend { - void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature); + void *(*shader_init)(const DWORD *byte_code, size_t byte_code_size, + const struct wined3d_shader_signature *output_signature); void (*shader_free)(void *data); void (*shader_read_header)(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version); void (*shader_read_instruction)(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins); @@ -893,12 +1264,16 @@ typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *); #define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001 #define WINED3D_SHADER_CAP_SRGB_WRITE 0x00000002 +#define WINED3D_SHADER_CAP_DOUBLE_PRECISION 0x00000004 struct shader_caps { - UINT vs_version; - UINT gs_version; - UINT ps_version; + unsigned int vs_version; + unsigned int hs_version; + unsigned int ds_version; + unsigned int gs_version; + unsigned int ps_version; + unsigned int cs_version; DWORD vs_uniform_count; DWORD ps_uniform_count; @@ -968,8 +1343,11 @@ struct ps_compile_args { WORD np2_fixup; WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */ WORD texcoords_initialized; /* MAX_TEXTURES, 8 */ - BOOL pointsprite; - BOOL flatshading; + DWORD pointsprite : 1; + DWORD flatshading : 1; + DWORD alpha_test_func : 3; + DWORD render_offscreen : 1; + DWORD padding : 26; }; enum fog_src_type { @@ -984,8 +1362,25 @@ struct vs_compile_args BYTE point_size : 1; BYTE per_vertex_point_size : 1; BYTE flatshading : 1; - BYTE padding : 4; + BYTE next_shader_type : 3; + BYTE padding : 1; WORD swizzle_map; /* MAX_ATTRIBS, 16 */ + unsigned int next_shader_input_count; +}; + +struct ds_compile_args +{ + enum wined3d_tessellator_output_primitive tessellator_output_primitive; + enum wined3d_tessellator_partitioning tessellator_partitioning; + unsigned int output_count : 16; + unsigned int next_shader_type : 3; + unsigned int render_offscreen : 1; + unsigned int padding : 12; +}; + +struct gs_compile_args +{ + unsigned int output_count; }; struct wined3d_context; @@ -996,12 +1391,12 @@ struct wined3d_vertex_pipe_ops; struct wined3d_shader_backend_ops { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); + void (*shader_precompile)(void *shader_priv, struct wined3d_shader *shader); void (*shader_select)(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state); + void (*shader_select_compute)(void *shader_priv, struct wined3d_context *context, + const struct wined3d_state *state); void (*shader_disable)(void *shader_priv, struct wined3d_context *context); - void (*shader_select_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info, - enum wined3d_gl_resource_type tex_type, const SIZE *ds_mask_size); - void (*shader_deselect_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info); void (*shader_update_float_vertex_constants)(struct wined3d_device *device, UINT start, UINT count); void (*shader_update_float_pixel_constants)(struct wined3d_device *device, UINT start, UINT count); void (*shader_load_constants)(void *shader_priv, struct wined3d_context *context, @@ -1029,84 +1424,32 @@ extern const struct wined3d_shader_backend_ops none_shader_backend DECLSPEC_HIDD #define D3DCOLOR_B_B(dw) (((dw) >> 0) & 0xff) #define D3DCOLOR_B_A(dw) (((dw) >> 24) & 0xff) -#define D3DCOLOR_R(dw) (((float) (((dw) >> 16) & 0xff)) / 255.0f) -#define D3DCOLOR_G(dw) (((float) (((dw) >> 8) & 0xff)) / 255.0f) -#define D3DCOLOR_B(dw) (((float) (((dw) >> 0) & 0xff)) / 255.0f) -#define D3DCOLOR_A(dw) (((float) (((dw) >> 24) & 0xff)) / 255.0f) - -#define D3DCOLORTOGLFLOAT4(dw, vec) do { \ - (vec)[0] = D3DCOLOR_R(dw); \ - (vec)[1] = D3DCOLOR_G(dw); \ - (vec)[2] = D3DCOLOR_B(dw); \ - (vec)[3] = D3DCOLOR_A(dw); \ -} while(0) +static inline void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_color, DWORD d3d_color) +{ + wined3d_color->r = D3DCOLOR_B_R(d3d_color) / 255.0f; + wined3d_color->g = D3DCOLOR_B_G(d3d_color) / 255.0f; + wined3d_color->b = D3DCOLOR_B_B(d3d_color) / 255.0f; + wined3d_color->a = D3DCOLOR_B_A(d3d_color) / 255.0f; +} #define HIGHEST_TRANSFORMSTATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */ +void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info, + const char *file, unsigned int line, const char *name) DECLSPEC_HIDDEN; + /* Checking of API calls */ /* --------------------- */ #ifndef WINE_NO_DEBUG_MSGS #define checkGLcall(A) \ do { \ - GLint err; \ - if (!__WINE_IS_DEBUG_ON(_ERR, __wine_dbch___default)) break; \ - err = gl_info->gl_ops.gl.p_glGetError(); \ - if (err == GL_NO_ERROR) { \ - TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \ - \ - } else do { \ - ERR(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \ - debug_glerror(err), err, A, __FILE__, __LINE__); \ - err = gl_info->gl_ops.gl.p_glGetError(); \ - } while (err != GL_NO_ERROR); \ + if (__WINE_IS_DEBUG_ON(_ERR, &__wine_dbch_d3d) \ + && !gl_info->supported[ARB_DEBUG_OUTPUT]) \ + wined3d_check_gl_call(gl_info, __FILE__, __LINE__, A); \ } while(0) #else #define checkGLcall(A) do {} while(0) #endif -enum wined3d_ffp_idx -{ - WINED3D_FFP_POSITION = 0, - WINED3D_FFP_BLENDWEIGHT = 1, - WINED3D_FFP_BLENDINDICES = 2, - WINED3D_FFP_NORMAL = 3, - WINED3D_FFP_PSIZE = 4, - WINED3D_FFP_DIFFUSE = 5, - WINED3D_FFP_SPECULAR = 6, - WINED3D_FFP_TEXCOORD0 = 7, - WINED3D_FFP_TEXCOORD1 = 8, - WINED3D_FFP_TEXCOORD2 = 9, - WINED3D_FFP_TEXCOORD3 = 10, - WINED3D_FFP_TEXCOORD4 = 11, - WINED3D_FFP_TEXCOORD5 = 12, - WINED3D_FFP_TEXCOORD6 = 13, - WINED3D_FFP_TEXCOORD7 = 14, - WINED3D_FFP_ATTRIBS_COUNT = 15, -}; - -enum wined3d_ffp_emit_idx -{ - WINED3D_FFP_EMIT_FLOAT1 = 0, - WINED3D_FFP_EMIT_FLOAT2 = 1, - WINED3D_FFP_EMIT_FLOAT3 = 2, - WINED3D_FFP_EMIT_FLOAT4 = 3, - WINED3D_FFP_EMIT_D3DCOLOR = 4, - WINED3D_FFP_EMIT_UBYTE4 = 5, - WINED3D_FFP_EMIT_SHORT2 = 6, - WINED3D_FFP_EMIT_SHORT4 = 7, - WINED3D_FFP_EMIT_UBYTE4N = 8, - WINED3D_FFP_EMIT_SHORT2N = 9, - WINED3D_FFP_EMIT_SHORT4N = 10, - WINED3D_FFP_EMIT_USHORT2N = 11, - WINED3D_FFP_EMIT_USHORT4N = 12, - WINED3D_FFP_EMIT_UDEC3 = 13, - WINED3D_FFP_EMIT_DEC3N = 14, - WINED3D_FFP_EMIT_FLOAT16_2 = 15, - WINED3D_FFP_EMIT_FLOAT16_4 = 16, - WINED3D_FFP_EMIT_INVALID = 17, - WINED3D_FFP_EMIT_COUNT = 18 -}; - struct wined3d_bo_address { GLuint buffer_object; @@ -1142,14 +1485,15 @@ struct wined3d_stream_info WORD use_map; /* MAX_ATTRIBS, 16 */ }; -#if defined(STAGING_CSMT) +void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, + const struct wined3d_state *state, const struct wined3d_gl_info *gl_info, + const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; + void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, - UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, - BOOL indexed) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, - UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ + int base_vertex_idx, unsigned int start_idx, unsigned int index_count, + unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN; +void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define eps 1e-8f @@ -1157,28 +1501,43 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1) +enum wined3d_pipeline +{ + WINED3D_PIPELINE_GRAPHICS, + WINED3D_PIPELINE_COMPUTE, + WINED3D_PIPELINE_COUNT, +}; + /* Routines and structures related to state management */ #define STATE_RENDER(a) (a) #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE)) -#define STATE_TEXTURESTAGE(stage, num) (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + 1 + (stage) * (WINED3D_HIGHEST_TEXTURE_STATE + 1) + (num)) -#define STATE_IS_TEXTURESTAGE(a) ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE)) +#define STATE_TEXTURESTAGE(stage, num) \ + (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + 1 + (stage) * (WINED3D_HIGHEST_TEXTURE_STATE + 1) + (num)) +#define STATE_IS_TEXTURESTAGE(a) \ + ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE)) /* + 1 because samplers start with 0 */ #define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num)) #define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1)) -#define STATE_SHADER(a) (STATE_SAMPLER(MAX_COMBINED_SAMPLERS) + (a)) -#define STATE_IS_SHADER(a) ((a) >= STATE_SHADER(0) && (a) < STATE_SHADER(WINED3D_SHADER_TYPE_COUNT)) +#define STATE_GRAPHICS_SHADER(a) (STATE_SAMPLER(MAX_COMBINED_SAMPLERS) + (a)) +#define STATE_IS_GRAPHICS_SHADER(a) \ + ((a) >= STATE_GRAPHICS_SHADER(0) && (a) < STATE_GRAPHICS_SHADER(WINED3D_SHADER_TYPE_GRAPHICS_COUNT)) -#define STATE_CONSTANT_BUFFER(a) (STATE_SHADER(WINED3D_SHADER_TYPE_COUNT) + (a)) -#define STATE_IS_CONSTANT_BUFFER(a) ((a) >= STATE_CONSTANT_BUFFER(0) && (a) < STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT)) +#define STATE_GRAPHICS_CONSTANT_BUFFER(a) (STATE_GRAPHICS_SHADER(WINED3D_SHADER_TYPE_GRAPHICS_COUNT) + (a)) +#define STATE_IS_GRAPHICS_CONSTANT_BUFFER(a) \ + ((a) >= STATE_GRAPHICS_CONSTANT_BUFFER(0) \ + && (a) < STATE_GRAPHICS_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GRAPHICS_COUNT)) -#define STATE_SHADER_RESOURCE_BINDING (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COUNT)) -#define STATE_IS_SHADER_RESOURCE_BINDING(a) ((a) == STATE_SHADER_RESOURCE_BINDING) +#define STATE_GRAPHICS_SHADER_RESOURCE_BINDING (STATE_GRAPHICS_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GRAPHICS_COUNT)) +#define STATE_IS_GRAPHICS_SHADER_RESOURCE_BINDING(a) ((a) == STATE_GRAPHICS_SHADER_RESOURCE_BINDING) -#define STATE_TRANSFORM(a) (STATE_SHADER_RESOURCE_BINDING + (a)) +#define STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING (STATE_GRAPHICS_SHADER_RESOURCE_BINDING + 1) +#define STATE_IS_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING) + +#define STATE_TRANSFORM(a) (STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING + (a)) #define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255))) #define STATE_STREAMSRC (STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)) + 1) @@ -1201,9 +1560,9 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT) #define STATE_CLIPPLANE(a) (STATE_SCISSORRECT + 1 + (a)) -#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIPPLANES - 1)) +#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIP_DISTANCES - 1)) -#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES)) +#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIP_DISTANCES)) #define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL) #define STATE_FRONTFACE (STATE_MATERIAL + 1) @@ -1224,7 +1583,34 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_COLOR_KEY (STATE_POINT_ENABLE + 1) #define STATE_IS_COLOR_KEY(a) ((a) == STATE_COLOR_KEY) -#define STATE_HIGHEST (STATE_COLOR_KEY) +#define STATE_STREAM_OUTPUT (STATE_COLOR_KEY + 1) +#define STATE_IS_STREAM_OUTPUT(a) ((a) == STATE_STREAM_OUTPUT) + +#define STATE_COMPUTE_OFFSET (STATE_STREAM_OUTPUT + 1) + +#define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) +#define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER) + +#define STATE_COMPUTE_CONSTANT_BUFFER (STATE_COMPUTE_SHADER + 1) +#define STATE_IS_COMPUTE_CONSTANT_BUFFER(a) ((a) == STATE_COMPUTE_CONSTANT_BUFFER) + +#define STATE_COMPUTE_SHADER_RESOURCE_BINDING (STATE_COMPUTE_CONSTANT_BUFFER + 1) +#define STATE_IS_COMPUTE_SHADER_RESOURCE_BINDING(a) ((a) == STATE_COMPUTE_SHADER_RESOURCE_BINDING) + +#define STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING (STATE_COMPUTE_SHADER_RESOURCE_BINDING + 1) +#define STATE_IS_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING) + +#define STATE_COMPUTE_HIGHEST (STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING) +#define STATE_HIGHEST (STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING) + +#define STATE_IS_COMPUTE(a) ((a) >= STATE_COMPUTE_OFFSET && (a) <= STATE_COMPUTE_HIGHEST) +#define STATE_COMPUTE_COUNT (STATE_COMPUTE_HIGHEST - STATE_COMPUTE_OFFSET + 1) + +#define STATE_SHADER(a) ((a) != WINED3D_SHADER_TYPE_COMPUTE ? STATE_GRAPHICS_SHADER(a) : STATE_COMPUTE_SHADER) +#define STATE_CONSTANT_BUFFER(a) \ + ((a) != WINED3D_SHADER_TYPE_COMPUTE ? STATE_GRAPHICS_CONSTANT_BUFFER(a) : STATE_COMPUTE_CONSTANT_BUFFER) +#define STATE_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == WINED3D_PIPELINE_GRAPHICS ? \ + STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING : STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING) enum fogsource { FOGSOURCE_FFP, @@ -1232,15 +1618,37 @@ enum fogsource { FOGSOURCE_COORD, }; -struct wined3d_occlusion_query +/* Direct3D terminology with little modifications. We do not have an issued + * state because only the driver knows about it, but we have a created state + * because D3D allows GetData() on a created query, but OpenGL doesn't. */ +enum wined3d_query_state { - struct list entry; - GLuint id; - struct wined3d_context *context; -#if defined(STAGING_CSMT) - DWORD samples; - BOOL started; -#endif /* STAGING_CSMT */ + QUERY_CREATED, + QUERY_SIGNALLED, + QUERY_BUILDING +}; + +struct wined3d_query_ops +{ + BOOL (*query_poll)(struct wined3d_query *query, DWORD flags); + BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); +}; + +struct wined3d_query +{ + LONG ref; + + void *parent; + const struct wined3d_parent_ops *parent_ops; + struct wined3d_device *device; + enum wined3d_query_state state; + enum wined3d_query_type type; + const void *data; + DWORD data_size; + const struct wined3d_query_ops *query_ops; + + LONG counter_main, counter_retrieved; + struct list poll_list_entry; }; union wined3d_gl_query_object @@ -1251,9 +1659,12 @@ union wined3d_gl_query_object struct wined3d_event_query { + struct wined3d_query query; + struct list entry; union wined3d_gl_query_object object; struct wined3d_context *context; + BOOL signalled; }; enum wined3d_event_query_result @@ -1271,53 +1682,105 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_ void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) DECLSPEC_HIDDEN; BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -struct wined3d_timestamp_query +struct wined3d_occlusion_query { + struct wined3d_query query; + + struct list entry; + GLuint id; + struct wined3d_context *context; + UINT64 samples; + BOOL started; +}; + +struct wined3d_timestamp_query +{ + struct wined3d_query query; + struct list entry; GLuint id; struct wined3d_context *context; -#if defined(STAGING_CSMT) UINT64 timestamp; }; void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -struct wined3d_fb_state +union wined3d_gl_so_statistics_query { - struct wined3d_rendertarget_view **render_targets; - struct wined3d_rendertarget_view *depth_stencil; - UINT rt_size; + GLuint id[2]; + struct + { + GLuint written; + GLuint generated; + } query; }; -static inline BOOL wined3d_fb_equal(const struct wined3d_fb_state *fb1, const struct wined3d_fb_state *fb2) +struct wined3d_so_statistics_query { - UINT i; + struct wined3d_query query; - if (fb1->depth_stencil != fb2->depth_stencil) - return FALSE; - if (fb1->rt_size != fb2->rt_size) - return FALSE; - for (i = 0; i < fb1->rt_size; i++) - if (fb1->render_targets[i] != fb2->render_targets[i]) - return FALSE; - return TRUE; -} - -static inline void wined3d_fb_copy(struct wined3d_fb_state *dst, const struct wined3d_fb_state *src) -{ - UINT i; - - dst->depth_stencil = src->depth_stencil; - for (i = 0; i < min(dst->rt_size, src->rt_size); i++) - dst->render_targets[i] = src->render_targets[i]; -} -#else /* STAGING_CSMT */ + struct list entry; + union wined3d_gl_so_statistics_query u; + struct wined3d_context *context; + unsigned int stream_idx; + struct wined3d_query_data_so_statistics statistics; + BOOL started; }; -void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ +void context_alloc_so_statistics_query(struct wined3d_context *context, + struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; +void context_free_so_statistics_query(struct wined3d_so_statistics_query *query) DECLSPEC_HIDDEN; + +union wined3d_gl_pipeline_statistics_query +{ + GLuint id[11]; + struct + { + GLuint vertices; + GLuint primitives; + GLuint vertex_shader; + GLuint tess_control_shader; + GLuint tess_eval_shader; + GLuint geometry_shader; + GLuint geometry_primitives; + GLuint fragment_shader; + GLuint compute_shader; + GLuint clipping_input; + GLuint clipping_output; + } query; +}; + +struct wined3d_pipeline_statistics_query +{ + struct wined3d_query query; + + struct list entry; + union wined3d_gl_pipeline_statistics_query u; + struct wined3d_context *context; + struct wined3d_query_data_pipeline_statistics statistics; + BOOL started; +}; + +void context_alloc_pipeline_statistics_query(struct wined3d_context *context, + struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; +void context_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query) DECLSPEC_HIDDEN; + +struct wined3d_gl_view +{ + GLenum target; + GLuint name; +}; + +struct wined3d_rendertarget_info +{ + struct wined3d_gl_view gl_view; + struct wined3d_resource *resource; + unsigned int sub_resource_idx; + unsigned int layer_count; +}; + +#define MAX_GL_FRAGMENT_SAMPLERS 32 struct wined3d_context { @@ -1333,12 +1796,15 @@ struct wined3d_context DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ -#if defined(STAGING_CSMT) - struct wined3d_fb_state current_fb; -#endif /* STAGING_CSMT */ + unsigned int dirty_compute_states[STATE_COMPUTE_COUNT / (sizeof(unsigned int) * CHAR_BIT) + 1]; + struct wined3d_device *device; struct wined3d_swapchain *swapchain; - struct wined3d_surface *current_rt; + struct + { + struct wined3d_texture *texture; + unsigned int sub_resource_idx; + } current_rt; DWORD tid; /* Thread ID which owns this context at the moment */ /* Stores some information about the context state for optimization */ @@ -1364,8 +1830,18 @@ struct wined3d_context DWORD use_immediate_mode_draw : 1; DWORD rebind_fbo : 1; DWORD needs_set : 1; + DWORD hdc_is_private : 1; + DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */ DWORD update_shader_resource_bindings : 1; - DWORD padding : 16; + DWORD update_compute_shader_resource_bindings : 1; + DWORD update_unordered_access_view_bindings : 1; + DWORD update_compute_unordered_access_view_bindings : 1; + DWORD uses_uavs : 1; + DWORD destroy_delayed : 1; + DWORD transform_feedback_active : 1; + DWORD transform_feedback_paused : 1; + DWORD padding : 7; + DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */ DWORD shader_update_mask; DWORD constant_update_mask; DWORD numbered_array_mask; @@ -1374,7 +1850,7 @@ struct wined3d_context UINT blit_w, blit_h; enum fogsource fog_source; DWORD active_texture; - DWORD texture_type[MAX_COMBINED_SAMPLERS]; + DWORD *texture_type; UINT instance_count; @@ -1383,6 +1859,7 @@ struct wined3d_context HGLRC restore_ctx; HDC restore_dc; int restore_pf; + HWND restore_pf_win; HGLRC glCtx; HWND win_handle; HDC hdc; @@ -1399,51 +1876,57 @@ struct wined3d_context struct fbo_entry *current_fbo; GLuint fbo_read_binding; GLuint fbo_draw_binding; - struct wined3d_surface **blit_targets; + struct wined3d_rendertarget_info *blit_targets; + struct wined3d_fbo_entry_key *fbo_key; GLenum *draw_buffers; DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */ /* Queries */ GLuint *free_occlusion_queries; - UINT free_occlusion_query_size; - UINT free_occlusion_query_count; + SIZE_T free_occlusion_query_size; + unsigned int free_occlusion_query_count; struct list occlusion_queries; union wined3d_gl_query_object *free_event_queries; - UINT free_event_query_size; - UINT free_event_query_count; + SIZE_T free_event_query_size; + unsigned int free_event_query_count; struct list event_queries; GLuint *free_timestamp_queries; - UINT free_timestamp_query_size; - UINT free_timestamp_query_count; + SIZE_T free_timestamp_query_size; + unsigned int free_timestamp_query_count; struct list timestamp_queries; + union wined3d_gl_so_statistics_query *free_so_statistics_queries; + SIZE_T free_so_statistics_query_size; + unsigned int free_so_statistics_query_count; + struct list so_statistics_queries; + + union wined3d_gl_pipeline_statistics_query *free_pipeline_statistics_queries; + SIZE_T free_pipeline_statistics_query_size; + unsigned int free_pipeline_statistics_query_count; + struct list pipeline_statistics_queries; + struct wined3d_stream_info stream_info; /* Fences for GL_APPLE_flush_buffer_range */ struct wined3d_event_query *buffer_queries[MAX_ATTRIBS]; unsigned int num_buffer_queries; - DWORD tex_unit_map[MAX_COMBINED_SAMPLERS]; - DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS]; + DWORD tex_unit_map[MAX_COMBINED_SAMPLERS]; + DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS]; /* Extension emulation */ GLint gl_fog_source; GLfloat fog_coord_value; GLfloat color[4], fogstart, fogend, fogcolor[4]; GLuint dummy_arbfp_prog; -#if defined(STAGING_CSMT) - - GLenum offscreenBuffer; -#else /* STAGING_CSMT */ }; struct wined3d_fb_state { struct wined3d_rendertarget_view **render_targets; struct wined3d_rendertarget_view *depth_stencil; -#endif /* STAGING_CSMT */ }; typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); @@ -1533,6 +2016,8 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; +struct wined3d_surface; + enum wined3d_blit_op { WINED3D_BLIT_OP_COLOR_BLIT, @@ -1543,75 +2028,79 @@ enum wined3d_blit_op WINED3D_BLIT_OP_DEPTH_BLIT, }; -/* Shaders for color conversions in blits. Do not do blit operations while - * already under the GL lock. */ -struct blit_shader +struct wined3d_blitter { - HRESULT (*alloc_private)(struct wined3d_device *device); - void (*free_private)(struct wined3d_device *device); - HRESULT (*set_shader)(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface, - const struct wined3d_color_key *color_key); - void (*unset_shader)(const struct wined3d_gl_info *gl_info); - BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format); - HRESULT (*color_fill)(struct wined3d_device *device, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color); - HRESULT (*depth_fill)(struct wined3d_device *device, - struct wined3d_rendertarget_view *view, const RECT *rect, float depth); - void (*blit_surface)(struct wined3d_device *device, enum wined3d_blit_op op, DWORD filter, - struct wined3d_surface *src_surface, const RECT *src_rect, - struct wined3d_surface *dst_surface, const RECT *dst_rect, - const struct wined3d_color_key *color_key); + const struct wined3d_blitter_ops *ops; + struct wined3d_blitter *next; }; -extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN; -extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN; -extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN; +struct wined3d_blitter_ops +{ + void (*blitter_destroy)(struct wined3d_blitter *blitter, struct wined3d_context *context); + void (*blitter_clear)(struct wined3d_blitter *blitter, struct wined3d_device *device, + unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, + const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil); + void (*blitter_blit)(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context, + struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, + struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect, + const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter); +}; + +void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, + const struct wined3d_device *device) DECLSPEC_HIDDEN; +struct wined3d_blitter *wined3d_cpu_blitter_create(void) DECLSPEC_HIDDEN; +void wined3d_fbo_blitter_create(struct wined3d_blitter **next, + const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; +void wined3d_ffp_blitter_create(struct wined3d_blitter **next, + const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSPEC_HIDDEN; -const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, - const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, - const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format) - DECLSPEC_HIDDEN; struct wined3d_context *context_acquire(const struct wined3d_device *device, - struct wined3d_surface *target) DECLSPEC_HIDDEN; + struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; -BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, +BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state, UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, - const struct wined3d_state *state) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ +void context_apply_compute_state(struct wined3d_context *context, + const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN; +BOOL context_apply_draw_state(struct wined3d_context *context, + const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN; void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit) DECLSPEC_HIDDEN; +void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) DECLSPEC_HIDDEN; +void context_bind_dummy_textures(const struct wined3d_device *device, + const struct wined3d_context *context) DECLSPEC_HIDDEN; void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) DECLSPEC_HIDDEN; void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN; -struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_surface *target, +struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_texture *target, const struct wined3d_format *ds_format) DECLSPEC_HIDDEN; HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN; void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN; void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN; +GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DECLSPEC_HIDDEN; +const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context, + const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN; +void context_gl_resource_released(struct wined3d_device *device, + GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN; +void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN; +void *context_map_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, + size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN; +struct wined3d_context *context_reacquire(const struct wined3d_device *device, + struct wined3d_context *context) DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; -void context_resource_unloaded(const struct wined3d_device *device, - struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; @@ -1621,8 +2110,8 @@ void context_state_drawbuf(struct wined3d_context *context, void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void context_stream_info_from_declaration(struct wined3d_context *context, - const struct wined3d_state *state, struct wined3d_stream_info *stream_info) DECLSPEC_HIDDEN; +void context_unmap_bo_address(struct wined3d_context *context, + const struct wined3d_bo_address *data, GLenum binding) DECLSPEC_HIDDEN; /***************************************************************************** * Internal representation of a light @@ -1696,6 +2185,7 @@ enum wined3d_pci_device CARD_AMD_RADEON_HD6300 = 0x9803, CARD_AMD_RADEON_HD6400 = 0x6770, CARD_AMD_RADEON_HD6410D = 0x9644, + CARD_AMD_RADEON_HD6480G = 0x9648, CARD_AMD_RADEON_HD6550D = 0x9640, CARD_AMD_RADEON_HD6600 = 0x6758, CARD_AMD_RADEON_HD6600M = 0x6741, @@ -1711,7 +2201,11 @@ enum wined3d_pci_device CARD_AMD_RADEON_HD8770 = 0x665c, CARD_AMD_RADEON_R3 = 0x9830, CARD_AMD_RADEON_R7 = 0x130f, - CARD_AMD_RADEON_R9 = 0x67b1, + CARD_AMD_RADEON_R9_285 = 0x6939, + CARD_AMD_RADEON_R9_290 = 0x67b1, + CARD_AMD_RADEON_R9_FURY = 0x7300, + CARD_AMD_RADEON_RX_460 = 0x67ef, + CARD_AMD_RADEON_RX_480 = 0x67df, CARD_NVIDIA_RIVA_128 = 0x0018, CARD_NVIDIA_RIVA_TNT = 0x0020, @@ -1746,10 +2240,12 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_9400GT = 0x042c, CARD_NVIDIA_GEFORCE_9500GT = 0x0640, CARD_NVIDIA_GEFORCE_9600GT = 0x0622, + CARD_NVIDIA_GEFORCE_9700MGT = 0x064a, CARD_NVIDIA_GEFORCE_9800GT = 0x0614, CARD_NVIDIA_GEFORCE_210 = 0x0a23, CARD_NVIDIA_GEFORCE_GT220 = 0x0a20, CARD_NVIDIA_GEFORCE_GT240 = 0x0ca3, + CARD_NVIDIA_GEFORCE_GTS250 = 0x0615, CARD_NVIDIA_GEFORCE_GTX260 = 0x05e2, CARD_NVIDIA_GEFORCE_GTX275 = 0x05e6, CARD_NVIDIA_GEFORCE_GTX280 = 0x05e1, @@ -1771,10 +2267,12 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX470 = 0x06cd, CARD_NVIDIA_GEFORCE_GTX480 = 0x06c0, CARD_NVIDIA_GEFORCE_GT520 = 0x1040, + CARD_NVIDIA_GEFORCE_GT525M = 0x0dec, CARD_NVIDIA_GEFORCE_GT540M = 0x0df4, CARD_NVIDIA_GEFORCE_GTX550 = 0x1244, CARD_NVIDIA_GEFORCE_GT555M = 0x04b8, CARD_NVIDIA_GEFORCE_GTX560TI = 0x1200, + CARD_NVIDIA_GEFORCE_GTX560M = 0x1251, CARD_NVIDIA_GEFORCE_GTX560 = 0x1201, CARD_NVIDIA_GEFORCE_GTX570 = 0x1081, CARD_NVIDIA_GEFORCE_GTX580 = 0x1080, @@ -1790,18 +2288,49 @@ enum wined3d_pci_device CARD_NVIDIA_GEFORCE_GTX660TI = 0x1183, CARD_NVIDIA_GEFORCE_GTX670 = 0x1189, CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1, + CARD_NVIDIA_GEFORCE_GTX675MX = 0x11a7, CARD_NVIDIA_GEFORCE_GTX680 = 0x1180, + CARD_NVIDIA_GEFORCE_GTX690 = 0x1188, + CARD_NVIDIA_GEFORCE_GT730 = 0x1287, + CARD_NVIDIA_GEFORCE_GT730M = 0x0fe1, + CARD_NVIDIA_GEFORCE_GT740M = 0x1292, CARD_NVIDIA_GEFORCE_GT750M = 0x0fe9, CARD_NVIDIA_GEFORCE_GTX750 = 0x1381, CARD_NVIDIA_GEFORCE_GTX750TI = 0x1380, CARD_NVIDIA_GEFORCE_GTX760 = 0x1187, + CARD_NVIDIA_GEFORCE_GTX760TI = 0x1193, CARD_NVIDIA_GEFORCE_GTX765M = 0x11e2, CARD_NVIDIA_GEFORCE_GTX770M = 0x11e0, CARD_NVIDIA_GEFORCE_GTX770 = 0x1184, CARD_NVIDIA_GEFORCE_GTX780 = 0x1004, CARD_NVIDIA_GEFORCE_GTX780TI = 0x100a, + CARD_NVIDIA_GEFORCE_GTXTITAN = 0x1005, + CARD_NVIDIA_GEFORCE_GTXTITANB = 0x100c, + CARD_NVIDIA_GEFORCE_GTXTITANX = 0x17c2, + CARD_NVIDIA_GEFORCE_GTXTITANZ = 0x1001, + CARD_NVIDIA_GEFORCE_820M = 0x0fed, + CARD_NVIDIA_GEFORCE_830M = 0x1340, + CARD_NVIDIA_GEFORCE_840M = 0x1341, + CARD_NVIDIA_GEFORCE_845M = 0x1344, + CARD_NVIDIA_GEFORCE_GTX850M = 0x1391, + CARD_NVIDIA_GEFORCE_GTX860M = 0x1392, /* Other PCI ID 0x119a */ + CARD_NVIDIA_GEFORCE_GTX870M = 0x1199, + CARD_NVIDIA_GEFORCE_GTX880M = 0x1198, + CARD_NVIDIA_GEFORCE_940M = 0x1347, + CARD_NVIDIA_GEFORCE_GTX950 = 0x1402, + CARD_NVIDIA_GEFORCE_GTX950M = 0x139a, + CARD_NVIDIA_GEFORCE_GTX960 = 0x1401, + CARD_NVIDIA_GEFORCE_GTX960M = 0x139b, CARD_NVIDIA_GEFORCE_GTX970 = 0x13c2, CARD_NVIDIA_GEFORCE_GTX970M = 0x13d8, + CARD_NVIDIA_GEFORCE_GTX980 = 0x13c0, + CARD_NVIDIA_GEFORCE_GTX980TI = 0x17c8, + CARD_NVIDIA_GEFORCE_GTX1050 = 0x1c81, + CARD_NVIDIA_GEFORCE_GTX1060 = 0x1c03, + CARD_NVIDIA_GEFORCE_GTX1070 = 0x1b81, + CARD_NVIDIA_GEFORCE_GTX1080 = 0x1b80, + CARD_NVIDIA_GEFORCE_GTX1080TI = 0x1b06, + CARD_NVIDIA_TITANX_PASCAL = 0x1b00, CARD_VMWARE_SVGA3D = 0x0405, @@ -1839,7 +2368,41 @@ enum wined3d_pci_device CARD_INTEL_IVBD = 0x0162, CARD_INTEL_IVBM = 0x0166, CARD_INTEL_IVBS = 0x015a, + CARD_INTEL_HWD = 0x0412, CARD_INTEL_HWM = 0x0416, + CARD_INTEL_I5100_1 = 0x0a22, + CARD_INTEL_I5100_2 = 0x0a2a, + CARD_INTEL_I5100_3 = 0x0a2b, + CARD_INTEL_I5100_4 = 0x0a2e, + CARD_INTEL_IP5200_1 = 0x0d22, + CARD_INTEL_IP5200_2 = 0x0d26, + CARD_INTEL_IP5200_3 = 0x0d2a, + CARD_INTEL_IP5200_4 = 0x0d2b, + CARD_INTEL_IP5200_5 = 0x0d2e, + CARD_INTEL_HD5300 = 0x161e, + CARD_INTEL_HD5500 = 0x1616, + CARD_INTEL_HD5600 = 0x1612, + CARD_INTEL_HD6000 = 0x1626, + CARD_INTEL_I6100 = 0x162b, + CARD_INTEL_IP6200 = 0x1622, + CARD_INTEL_IPP6300 = 0x162a, + CARD_INTEL_HD510_1 = 0x1902, + CARD_INTEL_HD510_2 = 0x1906, + CARD_INTEL_HD510_3 = 0x190b, + CARD_INTEL_HD515 = 0x191e, + CARD_INTEL_HD520_1 = 0x1916, + CARD_INTEL_HD520_2 = 0x1921, + CARD_INTEL_HD530_1 = 0x1912, + CARD_INTEL_HD530_2 = 0x191b, + CARD_INTEL_HDP530 = 0x191d, + CARD_INTEL_I540 = 0x1926, + CARD_INTEL_I550 = 0x1927, + CARD_INTEL_I555 = 0x192b, + CARD_INTEL_IP555 = 0x192d, + CARD_INTEL_IP580_1 = 0x1932, + CARD_INTEL_IP580_2 = 0x193b, + CARD_INTEL_IPP580_1 = 0x193a, + CARD_INTEL_IPP580_2 = 0x193d, }; struct wined3d_fbo_ops @@ -1858,12 +2421,16 @@ struct wined3d_fbo_ops void (WINE_GLAPI *glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers); void (WINE_GLAPI *glGenFramebuffers)(GLsizei n, GLuint *framebuffers); GLenum (WINE_GLAPI *glCheckFramebufferStatus)(GLenum target); + void (WINE_GLAPI *glFramebufferTexture)(GLenum target, GLenum attachment, + GLuint texture, GLint level); void (WINE_GLAPI *glFramebufferTexture1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void (WINE_GLAPI *glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void (WINE_GLAPI *glFramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); + void (WINE_GLAPI *glFramebufferTextureLayer)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLint layer); void (WINE_GLAPI *glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void (WINE_GLAPI *glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, @@ -1879,14 +2446,12 @@ struct wined3d_gl_limits UINT lights; UINT textures; UINT texture_coords; - UINT vertex_uniform_blocks; - UINT geometry_uniform_blocks; - UINT fragment_uniform_blocks; - UINT fragment_samplers; - UINT vertex_samplers; - UINT combined_samplers; + unsigned int uniform_blocks[WINED3D_SHADER_TYPE_COUNT]; + unsigned int samplers[WINED3D_SHADER_TYPE_COUNT]; + unsigned int graphics_samplers; + unsigned int combined_samplers; UINT general_combiners; - UINT clipplanes; + UINT user_clip_distances; UINT texture_size; UINT texture3d_size; float pointsize_max; @@ -1897,6 +2462,8 @@ struct wined3d_gl_limits UINT samples; UINT vertex_attribs; + unsigned int texture_buffer_offset_alignment; + UINT glsl_varyings; UINT glsl_vs_float_constants; UINT glsl_ps_float_constants; @@ -1912,6 +2479,11 @@ struct wined3d_gl_limits UINT arb_ps_temps; }; +void wined3d_gl_limits_get_texture_unit_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; +void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, + enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; + struct wined3d_gl_info { DWORD selected_gl_version; @@ -1942,43 +2514,6 @@ struct wined3d_driver_info DWORD version_low; }; -struct wined3d_d3d_limits -{ - UINT vs_version, gs_version, ps_version; - DWORD vs_uniform_count; - DWORD ps_uniform_count; - UINT varying_count; - UINT ffp_textures; - UINT ffp_blend_stages; - UINT ffp_vertex_blend_matrices; -}; - -typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data); -typedef void (WINE_GLAPI *wined3d_ffp_texcoord_func)(GLenum unit, const void *data); -extern wined3d_ffp_attrib_func specular_func_3ubv DECLSPEC_HIDDEN; - -struct wined3d_ffp_attrib_ops -{ - wined3d_ffp_attrib_func position[WINED3D_FFP_EMIT_COUNT]; - wined3d_ffp_attrib_func diffuse[WINED3D_FFP_EMIT_COUNT]; - wined3d_ffp_attrib_func specular[WINED3D_FFP_EMIT_COUNT]; - wined3d_ffp_attrib_func normal[WINED3D_FFP_EMIT_COUNT]; - wined3d_ffp_texcoord_func texcoord[WINED3D_FFP_EMIT_COUNT]; -}; - -struct wined3d_d3d_info -{ - struct wined3d_d3d_limits limits; - struct wined3d_ffp_attrib_ops ffp_attrib_ops; - BOOL xyzrhw; - BOOL emulated_flatshading; - BOOL ffp_generic_attributes; - BOOL vs_clipping; - BOOL shader_color_key; - DWORD valid_rt_mask; - DWORD wined3d_creation_flags; -}; - /* The adapter structure */ struct wined3d_adapter { @@ -1999,7 +2534,6 @@ struct wined3d_adapter const struct wined3d_vertex_pipe_ops *vertex_pipe; const struct fragment_pipeline *fragment_pipe; const struct wined3d_shader_backend_ops *shader_backend; - const struct blit_shader *blitter; }; struct wined3d_caps_gl_ctx @@ -2020,7 +2554,8 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN; UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN; -BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; +BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN; + void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN; enum projection_types @@ -2069,7 +2604,8 @@ struct ffp_frag_settings unsigned char color_key_enabled : 1; unsigned char pointsprite : 1; unsigned char flatshading : 1; - unsigned char padding : 5; + unsigned char alpha_test_func : 3; + unsigned char padding : 2; }; struct ffp_frag_desc @@ -2111,12 +2647,14 @@ enum wined3d_ffp_vs_fog_mode struct wined3d_ffp_vs_settings { - DWORD light_type : 24; /* MAX_ACTIVE_LIGHTS, 8 * 3 */ + DWORD point_light_count : 4; + DWORD spot_light_count : 4; + DWORD directional_light_count : 4; + DWORD parallel_point_light_count : 4; DWORD diffuse_source : 2; DWORD emissive_source : 2; DWORD ambient_source : 2; DWORD specular_source : 2; - DWORD transformed : 1; DWORD vertexblends : 2; DWORD clipping : 1; @@ -2124,13 +2662,15 @@ struct wined3d_ffp_vs_settings DWORD normalize : 1; DWORD lighting : 1; DWORD localviewer : 1; + DWORD point_size : 1; DWORD per_vertex_point_size : 1; DWORD fog_mode : 2; DWORD texcoords : 8; /* MAX_TEXTURES */ DWORD ortho_fog : 1; DWORD flatshading : 1; - DWORD padding : 10; + DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */ + DWORD padding : 2; DWORD texgen[MAX_TEXTURES]; }; @@ -2156,6 +2696,17 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN; BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN; +struct wined3d_rasterizer_state +{ + LONG refcount; + struct wined3d_rasterizer_state_desc desc; + + void *parent; + const struct wined3d_parent_ops *parent_ops; + + struct wined3d_device *device; +}; + struct wined3d_stream_output { struct wined3d_buffer *buffer; @@ -2177,20 +2728,18 @@ struct wined3d_stream_state struct wined3d_state { DWORD flags; -#if defined(STAGING_CSMT) - struct wined3d_fb_state fb; -#else /* STAGING_CSMT */ const struct wined3d_fb_state *fb; -#endif /* STAGING_CSMT */ struct wined3d_vertex_declaration *vertex_declaration; - struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; + struct wined3d_stream_output stream_output[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; struct wined3d_stream_state streams[MAX_STREAMS + 1 /* tesselated pseudo-stream */]; struct wined3d_buffer *index_buffer; enum wined3d_format_id index_format; - INT base_vertex_index; - INT load_base_vertex_index; /* Non-indexed drawing needs 0 here, indexed needs base_vertex_index. */ + unsigned int index_offset; + int base_vertex_index; + int load_base_vertex_index; /* Non-indexed drawing needs 0 here, indexed needs base_vertex_index. */ GLenum gl_primitive_type; + GLint gl_patch_vertices; struct wined3d_query *predicate; BOOL predicate_value; @@ -2198,21 +2747,22 @@ struct wined3d_state struct wined3d_buffer *cb[WINED3D_SHADER_TYPE_COUNT][MAX_CONSTANT_BUFFERS]; struct wined3d_sampler *sampler[WINED3D_SHADER_TYPE_COUNT][MAX_SAMPLER_OBJECTS]; struct wined3d_shader_resource_view *shader_resource_view[WINED3D_SHADER_TYPE_COUNT][MAX_SHADER_RESOURCE_VIEWS]; + struct wined3d_unordered_access_view *unordered_access_view[WINED3D_PIPELINE_COUNT][MAX_UNORDERED_ACCESS_VIEWS]; - BOOL vs_consts_b[MAX_CONST_B]; - INT vs_consts_i[MAX_CONST_I * 4]; - float *vs_consts_f; + BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; + struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; + struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; - BOOL ps_consts_b[MAX_CONST_B]; - INT ps_consts_i[MAX_CONST_I * 4]; - float *ps_consts_f; + BOOL ps_consts_b[WINED3D_MAX_CONSTS_B]; + struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I]; + struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS]; DWORD sampler_states[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; - struct wined3d_vec4 clip_planes[MAX_CLIPPLANES]; + struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES]; struct wined3d_material material; struct wined3d_viewport viewport; RECT scissor_rect; @@ -2224,6 +2774,7 @@ struct wined3d_state const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; + struct wined3d_rasterizer_state *rasterizer_state; }; #if defined(STAGING_CSMT) @@ -2236,7 +2787,7 @@ struct wined3d_gl_bo }; #endif /* STAGING_CSMT */ -#define WINED3D_UNMAPPED_STAGE ~0U +#define WINED3D_UNMAPPED_STAGE ~0u /* Multithreaded flag. Removed from the public header to signal that * wined3d_device_create() ignores it. */ @@ -2255,18 +2806,14 @@ struct wined3d_device LONG style; LONG exStyle; - /* X and GL Information */ - GLenum offscreenBuffer; - const struct wined3d_shader_backend_ops *shader_backend; void *shader_priv; void *fragment_priv; void *vertex_priv; - void *blit_priv; struct StateEntry StateTable[STATE_HIGHEST + 1]; /* Array of functions for states which are handled by more than one pipeline part */ APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1]; - const struct blit_shader *blitter; + struct wined3d_blitter *blitter; BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */ BYTE bCursorVisible : 1; @@ -2291,13 +2838,6 @@ struct wined3d_device struct wined3d_rendertarget_view *back_buffer_view; struct wined3d_swapchain **swapchains; UINT swapchain_count; -#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *auto_depth_stencil_view; - - struct list resources; /* a linked list to track resources created by the device */ - struct list shaders; /* a linked list to track shaders (pixel and vertex) */ - struct wine_rb_tree samplers; -#else /* STAGING_CSMT */ struct list resources; /* a linked list to track resources created by the device */ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ @@ -2305,12 +2845,7 @@ struct wined3d_device /* Render Target Support */ struct wined3d_fb_state fb; - struct wined3d_surface *onscreen_depth_stencil; struct wined3d_rendertarget_view *auto_depth_stencil_view; -#endif /* STAGING_CSMT */ - - /* For rendering to a texture using glCopyTexImage */ - GLuint depth_blt_texture; /* Cursor management */ UINT xHotSpot; @@ -2318,22 +2853,29 @@ struct wined3d_device UINT xScreenSpace; UINT yScreenSpace; UINT cursorWidth, cursorHeight; -#if !defined(STAGING_CSMT) struct wined3d_texture *cursor_texture; -#endif /* STAGING_CSMT */ HCURSOR hardwareCursor; /* The Wine logo texture */ struct wined3d_texture *logo_texture; /* Textures for when no other textures are mapped */ - UINT dummy_texture_2d[MAX_COMBINED_SAMPLERS]; - UINT dummy_texture_rect[MAX_COMBINED_SAMPLERS]; - UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS]; - UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS]; + struct + { + GLuint tex_1d; + GLuint tex_2d; + GLuint tex_rect; + GLuint tex_3d; + GLuint tex_cube; + GLuint tex_cube_array; + GLuint tex_1d_array; + GLuint tex_2d_array; + GLuint tex_buffer; + } dummy_textures; /* Default sampler used to emulate the direct resource access without using wined3d_sampler */ - GLuint default_sampler; + struct wined3d_sampler *default_sampler; + struct wined3d_sampler *null_sampler; /* Command stream */ struct wined3d_cs *cs; @@ -2355,23 +2897,12 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; -void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; -void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, - struct wined3d_texture *dst_texture) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, const struct wined3d_context *context) DECLSPEC_HIDDEN; -void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; -void device_create_default_sampler(struct wined3d_device *device); -void device_delete_opengl_contexts_cs(struct wined3d_device *device, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, - struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; -void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; #endif /* STAGING_CSMT */ static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) @@ -2388,15 +2919,13 @@ struct wined3d_resource_ops { ULONG (*resource_incref)(struct wined3d_resource *resource); ULONG (*resource_decref)(struct wined3d_resource *resource); + void (*resource_preload)(struct wined3d_resource *resource); void (*resource_unload)(struct wined3d_resource *resource); HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); + HRESULT (*resource_map_info)(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags); HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); -#if defined(STAGING_CSMT) - void (*resource_location_invalidated)(struct wined3d_resource *resource, DWORD location); - void (*resource_load_location)(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location); -#endif /* STAGING_CSMT */ }; struct wined3d_resource @@ -2404,6 +2933,7 @@ struct wined3d_resource LONG ref; LONG bind_count; LONG map_count; + LONG access_count; struct wined3d_device *device; enum wined3d_resource_type type; enum wined3d_gl_resource_type gl_type; @@ -2414,29 +2944,20 @@ struct wined3d_resource DWORD usage; enum wined3d_pool pool; DWORD access_flags; - DWORD draw_binding; - DWORD map_binding; + WORD draw_binding; + WORD map_binding; UINT width; UINT height; UINT depth; UINT size; DWORD priority; -#if defined(STAGING_CSMT) - void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; - UINT custom_row_pitch, custom_slice_pitch; - struct wined3d_gl_bo *buffer, *map_buffer; - struct list resource_list_entry; - DWORD locations; - LONG access_fence; - BOOL unmap_dirtify; -#else /* STAGING_CSMT */ void *heap_memory; - struct list resource_list_entry; -#endif /* STAGING_CSMT */ void *parent; const struct wined3d_parent_ops *parent_ops; const struct wined3d_resource_ops *resource_ops; + + struct list resource_list_entry; }; static inline ULONG wined3d_resource_incref(struct wined3d_resource *resource) @@ -2449,6 +2970,16 @@ static inline ULONG wined3d_resource_decref(struct wined3d_resource *resource) return resource->resource_ops->resource_decref(resource); } +static inline void wined3d_resource_acquire(struct wined3d_resource *resource) +{ + InterlockedIncrement(&resource->access_count); +} + +static inline void wined3d_resource_release(struct wined3d_resource *resource) +{ + InterlockedDecrement(&resource->access_count); +} + void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN; HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, @@ -2457,67 +2988,16 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; -BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_changed(struct wined3d_resource *resource, - struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; -BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; -void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; -void wined3d_resource_get_memory(const struct wined3d_resource *resource, - DWORD location, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; -void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, - UINT *slice_pitch) DECLSPEC_HIDDEN; -GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; -void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; -BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; -BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, - struct wined3d_context *context) DECLSPEC_HIDDEN; -BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context) DECLSPEC_HIDDEN; -DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; -HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_unmap_internal(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; - -static inline void wined3d_resource_inc_fence(struct wined3d_resource *resource) -{ - InterlockedIncrement(&resource->access_fence); -} - -static inline void wined3d_resource_dec_fence(struct wined3d_resource *resource) -{ - InterlockedDecrement(&resource->access_fence); -} - -static inline void wined3d_resource_wait_fence(struct wined3d_resource *resource) -{ - while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); -} -#else /* STAGING_CSMT */ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16 +#define WINED3D_CONSTANT_BUFFER_ALIGNMENT 16 struct gl_texture { @@ -2528,17 +3008,14 @@ struct gl_texture struct wined3d_texture_ops { - void (*texture_sub_resource_load)(struct wined3d_resource *sub_resource, - struct wined3d_context *context, BOOL srgb); - void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource, - const struct wined3d_box *dirty_region); - void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource); - void (*texture_sub_resource_invalidate_location)(struct wined3d_resource *sub_resource, DWORD location); - void (*texture_sub_resource_validate_location)(struct wined3d_resource *sub_resource, DWORD location); - void (*texture_sub_resource_upload_data)(struct wined3d_resource *sub_resource, - const struct wined3d_context *context, const struct wined3d_sub_resource_data *data); + void (*texture_upload_data)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch); + BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location); void (*texture_prepare_texture)(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb); + void (*texture_cleanup_sub_resources)(struct wined3d_texture *texture); }; #define WINED3D_TEXTURE_COND_NP2 0x00000001 @@ -2551,8 +3028,11 @@ struct wined3d_texture_ops #define WINED3D_TEXTURE_SRGB_VALID 0x00000080 #define WINED3D_TEXTURE_CONVERTED 0x00000100 #define WINED3D_TEXTURE_PIN_SYSMEM 0x00000200 -#define WINED3D_TEXTURE_DYNAMIC_MAP 0x00000400 -#define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000800 +#define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000400 +#define WINED3D_TEXTURE_GET_DC_LENIENT 0x00000800 +#define WINED3D_TEXTURE_DC_IN_USE 0x00001000 +#define WINED3D_TEXTURE_DISCARD 0x00002000 +#define WINED3D_TEXTURE_GET_DC 0x00004000 #define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001 @@ -2562,22 +3042,26 @@ struct wined3d_texture const struct wined3d_texture_ops *texture_ops; struct gl_texture texture_rgb, texture_srgb; struct wined3d_swapchain *swapchain; + unsigned int pow2_width; + unsigned int pow2_height; UINT layer_count; UINT level_count; + unsigned int download_count; + unsigned int sysmem_count; float pow2_matrix[16]; UINT lod; enum wined3d_texture_filter_type filter_type; DWORD sampler; DWORD flags; GLenum target; + DWORD update_map_binding; + + GLuint rb_multisample; + GLuint rb_resolved; -#if defined(STAGING_CSMT) - unsigned int row_pitch; -#else /* STAGING_CSMT */ void *user_memory; unsigned int row_pitch; unsigned int slice_pitch; -#endif /* STAGING_CSMT */ /* May only be accessed from the command stream worker thread. */ struct wined3d_texture_async @@ -2593,13 +3077,29 @@ struct wined3d_texture DWORD color_key_flags; } async; - struct + struct wined3d_texture_sub_resource { - struct wined3d_resource *resource; + void *parent; + const struct wined3d_parent_ops *parent_ops; + + union + { + struct wined3d_surface *surface; + } u; + unsigned int offset; + unsigned int size; + + unsigned int map_count; + DWORD locations; +#if !defined(STAGING_CSMT) + GLuint buffer_object; +#else /* STAGING_CSMT */ + struct wined3d_gl_bo *buffer; +#endif /* STAGING_CSMT */ } sub_resources[1]; }; -static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource) +static inline struct wined3d_texture *texture_from_resource(struct wined3d_resource *resource) { return CONTAINING_RECORD(resource, struct wined3d_texture, resource); } @@ -2610,104 +3110,78 @@ static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_t return srgb ? &texture->texture_srgb : &texture->texture_rgb; } +static inline unsigned int wined3d_texture_get_level_width(const struct wined3d_texture *texture, + unsigned int level) +{ + return max(1, texture->resource.width >> level); +} + +static inline unsigned int wined3d_texture_get_level_height(const struct wined3d_texture *texture, + unsigned int level) +{ + return max(1, texture->resource.height >> level); +} + +static inline unsigned int wined3d_texture_get_level_depth(const struct wined3d_texture *texture, + unsigned int level) +{ + return max(1, texture->resource.depth >> level); +} + +static inline unsigned int wined3d_texture_get_level_pow2_width(const struct wined3d_texture *texture, + unsigned int level) +{ + return max(1, texture->pow2_width >> level); +} + +static inline unsigned int wined3d_texture_get_level_pow2_height(const struct wined3d_texture *texture, + unsigned int level) +{ + return max(1, texture->pow2_height >> level); +} + void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_bind(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -void wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -BOOL wined3d_texture_check_block_align(const struct wined3d_texture *texture, +HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, unsigned int level, const struct wined3d_box *box) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ -void wined3d_texture_force_reload(struct wined3d_texture *texture) DECLSPEC_HIDDEN; +GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; +void wined3d_texture_invalidate_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_load(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +BOOL wined3d_texture_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN; void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) DECLSPEC_HIDDEN; +void wined3d_texture_validate_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; #define WINED3D_LOCATION_DISCARDED 0x00000001 #define WINED3D_LOCATION_SYSMEM 0x00000002 #define WINED3D_LOCATION_USER_MEMORY 0x00000004 -#define WINED3D_LOCATION_DIB 0x00000008 -#define WINED3D_LOCATION_BUFFER 0x00000010 -#define WINED3D_LOCATION_TEXTURE_RGB 0x00000020 -#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000040 -#define WINED3D_LOCATION_DRAWABLE 0x00000080 -#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000100 -#define WINED3D_LOCATION_RB_RESOLVED 0x00000200 +#define WINED3D_LOCATION_BUFFER 0x00000008 +#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010 +#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020 +#define WINED3D_LOCATION_DRAWABLE 0x00000040 +#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080 +#define WINED3D_LOCATION_RB_RESOLVED 0x00000100 const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; -struct wined3d_volume -{ - struct wined3d_resource resource; - struct wined3d_texture *container; - -#if defined(STAGING_CSMT) - GLint texture_level; - DWORD download_count; -#else /* STAGING_CSMT */ - DWORD locations; - GLint texture_level; - DWORD download_count; - GLuint pbo; -#endif /* STAGING_CSMT */ -}; - -static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource) -{ - return CONTAINING_RECORD(resource, struct wined3d_volume, resource); -} - -#if defined(STAGING_CSMT) -HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; -void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, - BOOL srgb_mode) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) DECLSPEC_HIDDEN; - -struct wined3d_surface_dib -{ - HBITMAP DIBsection; -#else /* STAGING_CSMT */ -BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; -void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, - BOOL srgb_mode) DECLSPEC_HIDDEN; -void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; - -struct wined3d_surface_dib -{ - HBITMAP DIBsection; - void *bitmap_data; -#endif /* STAGING_CSMT */ - UINT bitmap_size; -}; - struct wined3d_renderbuffer_entry { struct list entry; @@ -2716,66 +3190,44 @@ struct wined3d_renderbuffer_entry UINT height; }; +struct wined3d_fbo_resource +{ + GLuint object; + GLenum target; + GLuint level, layer; +}; + +#define WINED3D_FBO_ENTRY_FLAG_ATTACHED 0x1 +#define WINED3D_FBO_ENTRY_FLAG_DEPTH 0x2 +#define WINED3D_FBO_ENTRY_FLAG_STENCIL 0x4 + struct fbo_entry { struct list entry; - struct wined3d_surface **render_targets; - struct wined3d_surface *depth_stencil; - DWORD color_location, ds_location; + DWORD flags; DWORD rt_mask; - BOOL attached; GLuint id; -}; - -struct wined3d_surface_ops -{ - HRESULT (*surface_private_setup)(struct wined3d_surface *surface); -#if defined(STAGING_CSMT) - void (*surface_frontbuffer_updated)(struct wined3d_surface *surface); -#else /* STAGING_CSMT */ - void (*surface_unmap)(struct wined3d_surface *surface); -#endif /* STAGING_CSMT */ + struct wined3d_fbo_entry_key + { + DWORD rb_namespace; + struct wined3d_fbo_resource objects[1]; + } key; }; struct wined3d_surface { - struct wined3d_resource resource; - const struct wined3d_surface_ops *surface_ops; struct wined3d_texture *container; -#if defined(STAGING_CSMT) - DWORD flags; - - UINT pow2Width; - UINT pow2Height; - -#else /* STAGING_CSMT */ - DWORD locations; - - DWORD flags; - - UINT pow2Width; - UINT pow2Height; - - /* PBO */ - GLuint pbo; -#endif /* STAGING_CSMT */ - GLuint rb_multisample; - GLuint rb_resolved; GLenum texture_target; unsigned int texture_level; unsigned int texture_layer; - RECT lockedRect; - int lockCount; - /* For GetDC */ - struct wined3d_surface_dib dib; - HDC hDC; + HBITMAP bitmap; + HDC dc; struct list renderbuffers; const struct wined3d_renderbuffer_entry *current_renderbuffer; - SIZE ds_current_size; /* DirectDraw Overlay handling */ RECT overlay_srcrect; @@ -2785,115 +3237,47 @@ struct wined3d_surface struct list overlay_entry; }; -static inline struct wined3d_surface *surface_from_resource(struct wined3d_resource *resource) +static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface) { - return CONTAINING_RECORD(resource, struct wined3d_surface, resource); + return surface->texture_layer * surface->container->level_count + surface->texture_level; } -static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context) +static inline struct wined3d_texture_sub_resource *surface_get_sub_resource(struct wined3d_surface *surface) { - return !context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE] - && context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL; -} - -static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface, - const struct wined3d_context *context, BOOL srgb) -{ - return srgb && needs_separate_srgb_gl_texture(context) - ? surface->container->texture_srgb.name : surface->container->texture_rgb.name; + return &surface->container->sub_resources[surface_get_sub_resource_idx(surface)]; } HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void surface_set_dirty(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -HRESULT surface_color_fill(struct wined3d_surface *s, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; -HRESULT surface_create_dib_section(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, - unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void surface_load_ds_location(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; -void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -void surface_load_ds_location(struct wined3d_surface *surface, +BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, - struct wined3d_context *context) DECLSPEC_HIDDEN; -HRESULT surface_load_location(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ -HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; -void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, - DWORD location) DECLSPEC_HIDDEN; void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, - const struct wined3d_surface *rt) DECLSPEC_HIDDEN; -void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN; + const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; -HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, -#if defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; -HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, - struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; -HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - GLenum target, unsigned int level, unsigned int layer, DWORD flags, - struct wined3d_surface **surface) DECLSPEC_HIDDEN; -void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, - struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, - const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, - struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; -void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; -HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - GLenum target, unsigned int level, unsigned int layer, DWORD flags, - struct wined3d_surface **surface) DECLSPEC_HIDDEN; -void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -/* Surface flags: */ -#define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */ -#define SFLAG_DISCARD 0x00000002 /* ??? */ -#define SFLAG_DCINUSE 0x00000020 /* Set between GetDC and ReleaseDC calls. */ - struct wined3d_sampler { struct wine_rb_entry entry; LONG refcount; + GLuint name; struct wined3d_device *device; void *parent; + const struct wined3d_parent_ops *parent_ops; struct wined3d_sampler_desc desc; - GLuint name; }; -#if defined(STAGING_CSMT) -void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; +void wined3d_sampler_bind(struct wined3d_sampler *sampler, unsigned int unit, + struct wined3d_texture *texture, const struct wined3d_context *context) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ struct wined3d_vertex_declaration_element { const struct wined3d_format *format; @@ -2922,10 +3306,6 @@ struct wined3d_vertex_declaration BOOL half_float_conv_needed; }; -#if defined(STAGING_CSMT) -void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - -#endif /* STAGING_CSMT */ struct wined3d_saved_states { DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; @@ -2935,14 +3315,13 @@ struct wined3d_saved_states DWORD textureState[MAX_TEXTURES]; /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */ WORD samplerState[MAX_COMBINED_SAMPLERS]; /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */ DWORD clipplane; /* WINED3DMAXUSERCLIPPLANES, 32 */ - WORD pixelShaderConstantsB; /* MAX_CONST_B, 16 */ - WORD pixelShaderConstantsI; /* MAX_CONST_I, 16 */ - BOOL *pixelShaderConstantsF; - WORD vertexShaderConstantsB; /* MAX_CONST_B, 16 */ - WORD vertexShaderConstantsI; /* MAX_CONST_I, 16 */ - BOOL *vertexShaderConstantsF; + WORD pixelShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ + WORD pixelShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ + BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; + WORD vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ + WORD vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ + BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; DWORD textures : 20; /* MAX_COMBINED_SAMPLERS, 20 */ - DWORD primitive_type : 1; DWORD indices : 1; DWORD material : 1; DWORD viewport : 1; @@ -2950,7 +3329,7 @@ struct wined3d_saved_states DWORD pixelShader : 1; DWORD vertexShader : 1; DWORD scissorRect : 1; - DWORD padding : 4; + DWORD padding : 5; }; struct StageState { @@ -2972,17 +3351,17 @@ struct wined3d_stateblock unsigned int num_contained_render_states; DWORD contained_transform_states[HIGHEST_TRANSFORMSTATE + 1]; unsigned int num_contained_transform_states; - DWORD contained_vs_consts_i[MAX_CONST_I]; + DWORD contained_vs_consts_i[WINED3D_MAX_CONSTS_I]; unsigned int num_contained_vs_consts_i; - DWORD contained_vs_consts_b[MAX_CONST_B]; + DWORD contained_vs_consts_b[WINED3D_MAX_CONSTS_B]; unsigned int num_contained_vs_consts_b; - DWORD *contained_vs_consts_f; + DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; unsigned int num_contained_vs_consts_f; - DWORD contained_ps_consts_i[MAX_CONST_I]; + DWORD contained_ps_consts_i[WINED3D_MAX_CONSTS_I]; unsigned int num_contained_ps_consts_i; - DWORD contained_ps_consts_b[MAX_CONST_B]; + DWORD contained_ps_consts_b[WINED3D_MAX_CONSTS_B]; unsigned int num_contained_ps_consts_b; - DWORD *contained_ps_consts_f; + DWORD contained_ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; unsigned int num_contained_ps_consts_f; struct StageState contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)]; unsigned int num_contained_tss_states; @@ -2993,18 +3372,35 @@ struct wined3d_stateblock void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, + struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN; +struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, + unsigned int idx) DECLSPEC_HIDDEN; +void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, + const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, + DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; -struct wined3d_cs_list +enum wined3d_cs_queue_id { - struct list blocks; + WINED3D_CS_QUEUE_DEFAULT = 0, + WINED3D_CS_QUEUE_MAP, + WINED3D_CS_QUEUE_COUNT, }; -#define WINED3D_CS_QUEUE_SIZE 0x100000 -#define WINED3D_CS_SPIN_COUNT 10000000 +enum wined3d_push_constants +{ + WINED3D_PUSH_CONSTANTS_VS_F, + WINED3D_PUSH_CONSTANTS_PS_F, + WINED3D_PUSH_CONSTANTS_VS_I, + WINED3D_PUSH_CONSTANTS_PS_I, + WINED3D_PUSH_CONSTANTS_VS_B, + WINED3D_PUSH_CONSTANTS_PS_B, +}; + +#define WINED3D_CS_QUERY_POLL_INTERVAL 10u +#define WINED3D_CS_QUEUE_SIZE 0x100000u +#define WINED3D_CS_SPIN_COUNT 10000000u struct wined3d_cs_queue { @@ -3014,46 +3410,14 @@ struct wined3d_cs_queue struct wined3d_cs_ops { - void *(*require_space)(struct wined3d_cs *cs, size_t size); - void *(*require_space_prio)(struct wined3d_cs *cs, size_t size); - void (*submit)(struct wined3d_cs *cs, size_t size); - void (*submit_prio)(struct wined3d_cs *cs, size_t size); - void (*finish)(struct wined3d_cs *cs); - void (*finish_prio)(struct wined3d_cs *cs); -}; - -struct wined3d_cs -{ - const struct wined3d_cs_ops *ops; - struct wined3d_device *device; - struct wined3d_state state; - HANDLE thread; - DWORD thread_id; - struct wined3d_surface *onscreen_depth_stencil; - - struct wined3d_cs_queue queue, prio_queue; - - LONG pending_presents; - struct list query_poll_list; - - HANDLE event; - BOOL waiting_for_event; -}; - -struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; -void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, - struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, - DWORD flags) DECLSPEC_HIDDEN; -void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; - -struct wined3d_cs_ops -{ - void *(*require_space)(struct wined3d_cs *cs, size_t size); - void (*submit)(struct wined3d_cs *cs); +#if defined(STAGING_CSMT) + BOOL (*check_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); +#endif /* STAGING_CSMT */ + void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id); + void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); + void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id); + void (*push_constants)(struct wined3d_cs *cs, enum wined3d_push_constants p, + unsigned int start_idx, unsigned int count, const void *constants); }; struct wined3d_cs @@ -3062,22 +3426,46 @@ struct wined3d_cs struct wined3d_device *device; struct wined3d_fb_state fb; struct wined3d_state state; + HMODULE wined3d_module; + HANDLE thread; + DWORD thread_id; - size_t data_size; + struct wined3d_cs_queue queue[WINED3D_CS_QUEUE_COUNT]; + size_t data_size, start, end; void *data; + struct list query_poll_list; + + HANDLE event; + BOOL waiting_for_event; + LONG pending_presents; }; struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ - +void wined3d_cs_destroy_object(struct wined3d_cs *cs, + void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; +void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, + struct wined3d_texture *texture, unsigned int layer) DECLSPEC_HIDDEN; +void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource, + unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource, + unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags, + const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; -void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, - UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; +void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; +void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; +void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count, + int base_vertex_idx, unsigned int start_idx, unsigned int index_count, + unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN; +void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN; +void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - const RGNDATA *dirty_region, DWORD flags) DECLSPEC_HIDDEN; + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; @@ -3088,10 +3476,14 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, - enum wined3d_format_id format_id) DECLSPEC_HIDDEN; + enum wined3d_format_id format_id, unsigned int offset) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, unsigned int idx, BOOL enable) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, + struct wined3d_rasterizer_state *rasterizer_state) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, @@ -3116,114 +3508,38 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, enum wined3d_texture_stage_state state, DWORD value) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, const struct wined3d_matrix *matrix) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline, + unsigned int view_idx, struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, - const int *constants, UINT vector4i_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, - GLenum primitive_type) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) DECLSPEC_HIDDEN; -void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, - const RECT *dst_rect, struct wined3d_surface *src_surface, - const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; -void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, - struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; -void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) DECLSPEC_HIDDEN; -void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, - DWORD flags) DECLSPEC_HIDDEN; -void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, - UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; -void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; -void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; -void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, - struct wined3d_texture *dst) DECLSPEC_HIDDEN; -void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, - BYTE *mem) DECLSPEC_HIDDEN; -void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; -void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; -void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; -void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; -void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, - struct wined3d_resource *resource) DECLSPEC_HIDDEN; -void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; -void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; -void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; +void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ + unsigned int slice_pitch) DECLSPEC_HIDDEN; +void wined3d_cs_init_object(struct wined3d_cs *cs, + void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; +HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags) DECLSPEC_HIDDEN; +HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource, + unsigned int sub_resource_idx) DECLSPEC_HIDDEN; -/* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d - * allows GetData on a created issue, but opengl doesn't - */ -enum query_state { - QUERY_CREATED, - QUERY_SIGNALLED, - QUERY_BUILDING -}; - -struct wined3d_query_ops +static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p, + unsigned int start_idx, unsigned int count, const void *constants) { - HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); -#if defined(STAGING_CSMT) - BOOL (*query_poll)(struct wined3d_query *query); - BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); -#else /* STAGING_CSMT */ - HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); -#endif /* STAGING_CSMT */ -}; + cs->ops->push_constants(cs, p, start_idx, count, constants); +} -struct wined3d_query +static inline void wined3d_resource_wait_idle(struct wined3d_resource *resource) { - LONG ref; + const struct wined3d_cs *cs = resource->device->cs; - void *parent; - const struct wined3d_query_ops *query_ops; - struct wined3d_device *device; - enum query_state state; - enum wined3d_query_type type; - DWORD data_size; - void *extendedData; -#if defined(STAGING_CSMT) + if (!cs->thread || cs->thread_id == GetCurrentThreadId()) + return; - LONG counter_main, counter_retrieved; - struct list poll_list_entry; -}; - -void wined3d_query_destroy(struct wined3d_query *query) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -}; -#endif /* STAGING_CSMT */ + while (InterlockedCompareExchange(&resource->access_count, 0, 0)) + wined3d_pause(); +} /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other * fixed function semantics as D3DCOLOR or FLOAT16 */ @@ -3249,22 +3565,21 @@ struct wined3d_buffer GLuint buffer_object; GLenum buffer_object_usage; GLenum buffer_type_hint; + unsigned int bind_flags; DWORD flags; -#if defined(STAGING_CSMT) - BOOL ignore_discard; -#endif /* STAGING_CSMT */ + DWORD locations; void *map_ptr; struct wined3d_map_range *maps; - ULONG maps_size, modified_areas; + SIZE_T maps_size, modified_areas; struct wined3d_event_query *query; /* conversion stuff */ UINT decl_change_count, full_conversion_count; UINT draw_count; UINT stride; /* 0 if no conversion */ - UINT conversion_stride; /* 0 if no shifted conversion */ enum wined3d_buffer_conversion_type *conversion_map; /* NULL if no conversion */ + UINT conversion_stride; /* 0 if no shifted conversion */ }; static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource) @@ -3272,20 +3587,16 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_buffer, resource); } -void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, - struct wined3d_bo_address *data) DECLSPEC_HIDDEN; -BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; -void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, +DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, + struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; +void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; +void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; -void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; -void buffer_create_buffer_object(struct wined3d_buffer *This, - struct wined3d_context *context) DECLSPEC_HIDDEN; -void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ -void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ +BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; +HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, + struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; @@ -3297,36 +3608,42 @@ struct wined3d_rendertarget_view void *parent; const struct wined3d_parent_ops *parent_ops; + struct wined3d_gl_view gl_view; const struct wined3d_format *format; unsigned int format_flags; unsigned int sub_resource_idx; - unsigned int buffer_offset; + unsigned int layer_count; unsigned int width; unsigned int height; - unsigned int depth; + + struct wined3d_view_desc desc; }; static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( const struct wined3d_rendertarget_view *view) { - struct wined3d_resource *resource; struct wined3d_texture *texture; if (!view || view->resource->type != WINED3D_RTYPE_TEXTURE_2D) return NULL; - texture = wined3d_texture_from_resource(view->resource); - if (!(resource = wined3d_texture_get_sub_resource(texture, view->sub_resource_idx))) - return NULL; + texture = texture_from_resource(view->resource); - return surface_from_resource(resource); + return texture->sub_resources[view->sub_resource_idx].u.surface; } -#if defined(STAGING_CSMT) -void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view, + const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view, + DWORD location) DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_load_location(struct wined3d_rendertarget_view *view, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view *view, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, + DWORD location) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ struct wined3d_shader_resource_view { LONG refcount; @@ -3334,17 +3651,41 @@ struct wined3d_shader_resource_view struct wined3d_resource *resource; void *parent; const struct wined3d_parent_ops *parent_ops; + + struct wined3d_gl_view gl_view; + const struct wined3d_format *format; + + struct wined3d_view_desc desc; }; +void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view, unsigned int unit, + struct wined3d_sampler *sampler, struct wined3d_context *context) DECLSPEC_HIDDEN; + +struct wined3d_unordered_access_view +{ + LONG refcount; + + struct wined3d_resource *resource; + void *parent; + const struct wined3d_parent_ops *parent_ops; + + struct wined3d_gl_view gl_view; + const struct wined3d_format *format; + GLuint counter_bo; + + struct wined3d_view_desc desc; +}; + +void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view, + const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) DECLSPEC_HIDDEN; +void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view, + DWORD location) DECLSPEC_HIDDEN; + struct wined3d_swapchain_ops { - void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, -#if defined(STAGING_CSMT) - const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil); -#else /* STAGING_CSMT */ - const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags); -#endif /* STAGING_CSMT */ + void (*swapchain_present)(struct wined3d_swapchain *swapchain, + const RECT *src_rect, const RECT *dst_rect, DWORD flags); + void (*swapchain_frontbuffer_updated)(struct wined3d_swapchain *swapchain); }; struct wined3d_swapchain @@ -3359,10 +3700,12 @@ struct wined3d_swapchain struct wined3d_texture *front_buffer; struct wined3d_swapchain_desc desc; struct wined3d_display_mode original_mode, d3d_mode; + RECT original_window_rect; struct wined3d_gamma_ramp orig_gamma; BOOL render_to_fbo, reapply_mode; const struct wined3d_format *ds_format; struct wined3d_palette *palette; + RECT front_buffer_update; LONG prev_time, frames; /* Performance tracking */ @@ -3376,17 +3719,12 @@ struct wined3d_swapchain HWND backup_wnd; }; -void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN; - void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -HRESULT swapchain_create_context_cs(struct wined3d_device *device, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ +void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; /***************************************************************************** * Utility function prototypes @@ -3394,6 +3732,7 @@ HRESULT swapchain_create_context_cs(struct wined3d_device *device, /* Trace routines */ const char *debug_box(const struct wined3d_box *box) DECLSPEC_HIDDEN; +const char *debug_color(const struct wined3d_color *color) DECLSPEC_HIDDEN; const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx) DECLSPEC_HIDDEN; const char *debug_d3dformat(enum wined3d_format_id format_id) DECLSPEC_HIDDEN; const char *debug_d3ddevicetype(enum wined3d_device_type device_type) DECLSPEC_HIDDEN; @@ -3409,11 +3748,16 @@ const char *debug_d3dsamplerstate(enum wined3d_sampler_state state) DECLSPEC_HID const char *debug_d3dstate(DWORD state) DECLSPEC_HIDDEN; const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type) DECLSPEC_HIDDEN; const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) DECLSPEC_HIDDEN; +const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN; const char *debug_d3dtstype(enum wined3d_transform_state tstype) DECLSPEC_HIDDEN; const char *debug_d3dpool(enum wined3d_pool pool) DECLSPEC_HIDDEN; +const char *debug_fboattachment(GLenum attachment) DECLSPEC_HIDDEN; const char *debug_fbostatus(GLenum status) DECLSPEC_HIDDEN; const char *debug_glerror(GLenum error) DECLSPEC_HIDDEN; -const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN; +const char *debug_ivec4(const struct wined3d_ivec4 *v) DECLSPEC_HIDDEN; +const char *debug_uvec4(const struct wined3d_uvec4 *v) DECLSPEC_HIDDEN; +const char *debug_shader_type(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN; +const char *debug_vec4(const struct wined3d_vec4 *v) DECLSPEC_HIDDEN; void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN; BOOL is_invalid_op(const struct wined3d_state *state, int stage, @@ -3501,27 +3845,56 @@ int shader_addline(struct wined3d_string_buffer *buffer, const char *fmt, ...) P BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc) DECLSPEC_HIDDEN; int shader_vaddline(struct wined3d_string_buffer *buffer, const char *fmt, va_list args) DECLSPEC_HIDDEN; -/* Vertex shader utility functions */ -BOOL vshader_get_input(const struct wined3d_shader *shader, - BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN; +struct wined3d_shader_phase +{ + const DWORD *start; + const DWORD *end; + unsigned int instance_count; + unsigned int temporary_count; +}; struct wined3d_vertex_shader { struct wined3d_shader_attribute attributes[MAX_ATTRIBS]; }; +struct wined3d_hull_shader +{ + struct + { + struct wined3d_shader_phase *control_point; + unsigned int fork_count; + unsigned int join_count; + struct wined3d_shader_phase *fork; + SIZE_T fork_size; + struct wined3d_shader_phase *join; + SIZE_T join_size; + } phases; + unsigned int output_vertex_count; + enum wined3d_tessellator_output_primitive tessellator_output_primitive; + enum wined3d_tessellator_partitioning tessellator_partitioning; +}; + +struct wined3d_domain_shader +{ + enum wined3d_tessellator_domain tessellator_domain; +}; + struct wined3d_geometry_shader { enum wined3d_primitive_type input_type; enum wined3d_primitive_type output_type; - UINT vertices_out; + unsigned int vertices_out; + unsigned int instance_count; + + struct wined3d_stream_output_desc so_desc; }; struct wined3d_pixel_shader { /* Pixel shader input semantics */ DWORD input_reg_map[MAX_REG_INPUT]; - BOOL input_reg_used[MAX_REG_INPUT]; + DWORD input_reg_used; /* MAX_REG_INPUT, 32 */ unsigned int declared_in_count; /* Some information about the shader behavior */ @@ -3529,6 +3902,11 @@ struct wined3d_pixel_shader DWORD color0_reg; }; +struct wined3d_compute_shader +{ + struct wined3d_shader_thread_group_size thread_group_size; +}; + struct wined3d_shader { LONG ref; @@ -3555,6 +3933,7 @@ struct wined3d_shader struct wined3d_shader_signature input_signature; struct wined3d_shader_signature output_signature; + struct wined3d_shader_signature patch_constant_signature; char *signature_strings; /* Pointer to the parent device */ @@ -3564,8 +3943,11 @@ struct wined3d_shader union { struct wined3d_vertex_shader vs; + struct wined3d_hull_shader hs; + struct wined3d_domain_shader ds; struct wined3d_geometry_shader gs; struct wined3d_pixel_shader ps; + struct wined3d_compute_shader cs; } u; }; @@ -3574,21 +3956,27 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN; +BOOL vshader_get_input(const struct wined3d_shader *shader, + BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN; void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; +void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + struct ds_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN; + +void find_gs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, + struct gs_compile_args *args) DECLSPEC_HIDDEN; + void string_buffer_clear(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN; BOOL string_buffer_init(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN; void string_buffer_free(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN; unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max) DECLSPEC_HIDDEN; -void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, - const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; +HRESULT shader_generate_code(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, + const struct wined3d_shader_reg_maps *reg_maps, void *backend_ctx, + const DWORD *start, const DWORD *end) DECLSPEC_HIDDEN; BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -void shader_cleanup(struct wined3d_shader *shader) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) { @@ -3632,7 +4020,7 @@ static inline void shader_get_position_fixup(const struct wined3d_context *conte { float center_offset; - if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; @@ -3724,7 +4112,6 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_RENDERTARGET 0x00000010 #define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040 #define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080 -#define WINED3DFMT_FLAG_GETDC 0x00000100 #define WINED3DFMT_FLAG_FLOAT 0x00000200 #define WINED3DFMT_FLAG_BUMPMAP 0x00000400 #define WINED3DFMT_FLAG_SRGB_READ 0x00000800 @@ -3756,6 +4143,7 @@ struct wined3d_format { enum wined3d_format_id id; + D3DDDIFORMAT ddi_format; DWORD red_size; DWORD green_size; DWORD blue_size; @@ -3777,7 +4165,7 @@ struct wined3d_format GLenum gl_vtx_type; GLint gl_vtx_format; GLboolean gl_normalized; - unsigned int component_size; + unsigned int attribute_size; GLint glInternal; GLint glGammaInternal; @@ -3791,32 +4179,44 @@ struct wined3d_format struct color_fixup_desc color_fixup; void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch, UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth); + + enum wined3d_format_id typeless_id; + GLenum gl_view_class; }; const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, - enum wined3d_format_id format_id) DECLSPEC_HIDDEN; -#if defined(STAGING_CSMT) -UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width) DECLSPEC_HIDDEN; -#else /* STAGING_CSMT */ + enum wined3d_format_id format_id, unsigned int resource_usage) DECLSPEC_HIDDEN; void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN; -#endif /* STAGING_CSMT */ UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN; -DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, +DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color) DECLSPEC_HIDDEN; -BOOL wined3d_format_convert_color_to_float(const struct wined3d_format *format, - const struct wined3d_palette *palette, DWORD color, struct wined3d_color *float_color) DECLSPEC_HIDDEN; void wined3d_format_get_float_color_key(const struct wined3d_format *format, const struct wined3d_color_key *key, struct wined3d_color *float_colors) 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; +BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) DECLSPEC_HIDDEN; + +static inline BOOL wined3d_format_is_typeless(const struct wined3d_format *format) +{ + return format->id == format->typeless_id && format->id != WINED3DFMT_UNKNOWN; +} + +static inline void *wined3d_calloc(SIZE_T count, SIZE_T size) +{ + if (count > ~(SIZE_T)0 / size) + return NULL; + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * size); +} + static inline BOOL use_vs(const struct wined3d_state *state) { /* Check state->vertex_declaration to allow this to be used before the * stream info is validated, for example in device_update_tex_unit_map(). */ - return state->shader[WINED3D_SHADER_TYPE_VERTEX] && !state->vertex_declaration->position_transformed; + return state->shader[WINED3D_SHADER_TYPE_VERTEX] + && (!state->vertex_declaration || !state->vertex_declaration->position_transformed); } static inline BOOL use_ps(const struct wined3d_state *state) @@ -3832,12 +4232,56 @@ static inline void context_apply_state(struct wined3d_context *context, state_table[rep].apply(context, state, rep); } +static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, + const struct wined3d_texture *texture) +{ + unsigned int flags = texture->resource.format_flags + & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE); + + return (!context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE] + || (flags && flags != (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE))) + && context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL; +} + static inline BOOL needs_srgb_write(const struct wined3d_context *context, const struct wined3d_state *state, const struct wined3d_fb_state *fb) { return (!(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) || state->render_states[WINED3D_RS_SRGBWRITEENABLE]) - && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; + && fb->render_targets[0] && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; +} + +static inline GLuint wined3d_texture_get_texture_name(const struct wined3d_texture *texture, + const struct wined3d_context *context, BOOL srgb) +{ + return srgb && needs_separate_srgb_gl_texture(context, texture) + ? texture->texture_srgb.name : texture->texture_rgb.name; +} + +static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format) +{ + return gl_info->supported[ARB_TEXTURE_SWIZZLE] && !is_complex_fixup(format->color_fixup) + && !is_scaling_fixup(format->color_fixup); +} + +static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context) +{ + struct wined3d_texture *texture = context->current_rt.texture; + + if (!texture) + return NULL; + return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface; +} + +static inline void wined3d_from_cs(struct wined3d_cs *cs) +{ + if (cs->thread) + assert(cs->thread_id == GetCurrentThreadId()); +} + +static inline void wined3d_not_from_cs(struct wined3d_cs *cs) +{ + assert(cs->thread_id != GetCurrentThreadId()); } BOOL wined3d_dxtn_init(void) DECLSPEC_HIDDEN; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index a52539c08e1..516323bedcc 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -22,13 +22,13 @@ reactos/sdk/tools/wpp # Synced to WineStaging-2.9 The following libraries are shared with Wine. reactos/dll/directx/wine/amstream # Synced to WineStaging-2.9 -reactos/dll/directx/wine/d3d8 # Synced to WineStaging-1.9.4 -reactos/dll/directx/wine/d3d9 # Synced to WineStaging-1.9.4 +reactos/dll/directx/wine/d3d8 # Synced to WineStaging-2.9 +reactos/dll/directx/wine/d3d9 # Synced to WineStaging-2.9 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-1.9.4 reactos/dll/directx/wine/d3drm # Synced to WineStaging-2.9 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-1.9.4 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-2.9 -reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.9.4 +reactos/dll/directx/wine/ddraw # Synced to WineStaging-2.9 reactos/dll/directx/wine/devenum # Synced to WineStaging-2.9 reactos/dll/directx/wine/dinput # Synced to WineStaging-2.9 reactos/dll/directx/wine/dinput8 # Synced to WineStaging-2.9 @@ -40,7 +40,7 @@ reactos/dll/directx/wine/dxdiagn # Synced to WineStaging-2.9 reactos/dll/directx/wine/msdmo # Synced to WineStaging-2.9 reactos/dll/directx/wine/qedit # Synced to WineStaging-2.9 reactos/dll/directx/wine/quartz # Synced to WineStaging-2.9 -reactos/dll/directx/wine/wined3d # Synced to WineStaging-1.9.4 +reactos/dll/directx/wine/wined3d # Synced to WineStaging-2.9 reactos/dll/win32/activeds # Synced to WineStaging-2.9 reactos/dll/win32/actxprxy # Synced to WineStaging-2.9 diff --git a/reactos/sdk/include/reactos/wine/wgl.h b/reactos/sdk/include/reactos/wine/wgl.h index 23b4a5feef7..4a46c9585c9 100644 --- a/reactos/sdk/include/reactos/wine/wgl.h +++ b/reactos/sdk/include/reactos/wine/wgl.h @@ -40,5510 +40,5632 @@ typedef unsigned short GLushort; typedef INT_PTR GLvdpauSurfaceNV; typedef void GLvoid; -#define GL_1PASS_EXT 0x80A1 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2D 0x0600 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_2_BYTES 0x1407 -#define GL_2_BYTES_NV 0x1407 -#define GL_3D 0x0601 -#define GL_3DC_XY_AMD 0x87FA -#define GL_3DC_X_AMD 0x87F9 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_3_BYTES 0x1408 -#define GL_3_BYTES_NV 0x1408 -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_EXT 0x80CC -#define GL_422_REV_AVERAGE_EXT 0x80CF -#define GL_422_REV_EXT 0x80CD -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_4_BYTES 0x1409 -#define GL_4_BYTES_NV 0x1409 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_ABGR_EXT 0x8000 -#define GL_ACCUM 0x0100 -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_ACTIVE_PROGRAM_EXT 0x8B8D -#define GL_ACTIVE_RESOURCES 0x92F5 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -#define GL_ACTIVE_SUBROUTINES 0x8DE5 -#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 -#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_VARIABLES 0x9305 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_ADD 0x0104 -#define GL_ADD_ATI 0x8963 -#define GL_ADD_BLEND_IMG 0x8C09 -#define GL_ADD_SIGNED 0x8574 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_ALL_SHADER_BITS 0xFFFFFFFF -#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_ALPHA 0x1906 -#define GL_ALPHA12 0x803D -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16 0x803E -#define GL_ALPHA16F_ARB 0x881C -#define GL_ALPHA16F_EXT 0x881C -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_ALPHA16_EXT 0x803E -#define GL_ALPHA16_SNORM 0x9018 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_ALPHA32F_EXT 0x8816 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_ALPHA4 0x803B -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA8_OES 0x803C -#define GL_ALPHA8_SNORM 0x9014 -#define GL_ALPHA_BIAS 0x0D1D -#define GL_ALPHA_BITS 0x0D55 -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#define GL_ALPHA_MAX_SGIX 0x8321 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_REF_COMMAND_NV 0x000F -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_SNORM 0x9010 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 -#define GL_ALPHA_TEST_QCOM 0x0BC0 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_ALREADY_SIGNALED_APPLE 0x911A -#define GL_ALWAYS 0x0207 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_AMBIENT 0x1200 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_AND 0x1501 -#define GL_AND_INVERTED 0x1504 -#define GL_AND_REVERSE 0x1502 -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A -#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F -#define GL_ARC_TO_NV 0xFE -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -#define GL_ARRAY_SIZE 0x92FB -#define GL_ARRAY_STRIDE 0x92FE -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_ASYNC_MARKER_SGIX 0x8329 -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#define GL_ATC_RGB_AMD 0x8C92 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 -#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 -#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 -#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 -#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 -#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 -#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ATTENUATION_EXT 0x834D -#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_AUTO_GENERATE_MIPMAP 0x8295 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_AUX_BUFFERS 0x0C00 -#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 -#define GL_AVERAGE_EXT 0x8335 -#define GL_AVERAGE_HP 0x8160 -#define GL_BACK 0x0405 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_RIGHT 0x0403 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_BEVEL_NV 0x90A6 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_BGRA8_EXT 0x93A1 -#define GL_BGRA_EXT 0x80E1 -#define GL_BGRA_IMG 0x80E1 -#define GL_BGRA_INTEGER 0x8D9B -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_BGR_EXT 0x80E0 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BIAS_BIT_ATI 0x00000008 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BITMAP 0x1A00 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_BLEND 0x0BE2 -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_COLOR_COMMAND_NV 0x000B -#define GL_BLEND_COLOR_EXT 0x8005 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_DST_ALPHA_OES 0x80CA -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_DST_RGB_OES 0x80C8 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -#define GL_BLEND_EQUATION_ALPHA_OES 0x883D -#define GL_BLEND_EQUATION_EXT 0x8009 -#define GL_BLEND_EQUATION_OES 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_RGB_OES 0x8009 -#define GL_BLEND_OVERLAP_NV 0x9281 -#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -#define GL_BLEND_SRC_ALPHA_OES 0x80CB -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_SRC_RGB_OES 0x80C9 -#define GL_BLOCK_INDEX 0x92FD -#define GL_BLUE 0x1905 -#define GL_BLUE_BIAS 0x0D1B -#define GL_BLUE_BITS 0x0D54 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_BLUE_NV 0x1905 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BOLD_BIT_NV 0x01 -#define GL_BOOL 0x8B56 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_BROWSER_DEFAULT_WEBGL 0x9244 -#define GL_BUFFER 0x82E0 -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_ACCESS_OES 0x88BB -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D -#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F -#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F -#define GL_BUFFER_KHR 0x82E0 -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAPPED_OES 0x88BC -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_BUFFER_MAP_POINTER_OES 0x88BD -#define GL_BUFFER_OBJECT_APPLE 0x85B3 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_STORAGE_FLAGS 0x8220 -#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 -#define GL_BUFFER_USAGE 0x8765 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_BUFFER_VARIABLE 0x92E5 -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_TARGET_ATI 0x877C -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_BYTE 0x1400 -#define GL_C3F_V3F 0x2A24 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#define GL_CAVEAT_SUPPORT 0x82B8 -#define GL_CCW 0x0901 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_CLAMP 0x2900 -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#define GL_CLAMP_TO_BORDER_EXT 0x812D -#define GL_CLAMP_TO_BORDER_NV 0x812D -#define GL_CLAMP_TO_BORDER_OES 0x812D -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLEAR 0x1500 -#define GL_CLEAR_BUFFER 0x82B4 -#define GL_CLEAR_TEXTURE 0x9365 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 -#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_STORAGE_BIT 0x0200 -#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 -#define GL_CLIP_DEPTH_MODE 0x935D -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE0_APPLE 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE1_APPLE 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE2_APPLE 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE3_APPLE 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE4_APPLE 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE5_APPLE 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE6_APPLE 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_CLIP_DISTANCE7_APPLE 0x3007 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_ORIGIN 0x935C -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE0_IMG 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE1_IMG 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE2_IMG 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE3_IMG 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE4_IMG 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_CLIP_PLANE5_IMG 0x3005 -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#define GL_CLOSE_PATH_NV 0x00 -#define GL_CMYKA_EXT 0x800D -#define GL_CMYK_EXT 0x800C -#define GL_CND0_ATI 0x896B -#define GL_CND_ATI 0x896A -#define GL_COEFF 0x0A00 -#define GL_COLOR 0x1800 -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_COLORBURN_KHR 0x929A -#define GL_COLORBURN_NV 0x929A -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORDODGE_NV 0x9299 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_COLOR_ARRAY 0x8076 -#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 -#define GL_COLOR_ATTACHMENT0_OES 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT10_NV 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT11_NV 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT12_NV 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT13_NV 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT14_NV 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_COLOR_ATTACHMENT15_NV 0x8CEF -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 -#define GL_COLOR_ATTACHMENT_EXT 0x90F0 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 -#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 -#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 -#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 -#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 -#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 -#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 -#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_COMPONENTS 0x8283 -#define GL_COLOR_ENCODING 0x8296 -#define GL_COLOR_EXT 0x1800 -#define GL_COLOR_FLOAT_APPLE 0x8A0F -#define GL_COLOR_INDEX 0x1900 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEXES 0x1603 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_COLOR_RENDERABLE 0x8286 -#define GL_COLOR_SAMPLES_NV 0x8E20 -#define GL_COLOR_SUM 0x8458 -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_COLOR_TABLE 0x80D0 -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_COMBINE 0x8570 -#define GL_COMBINE4_NV 0x8503 -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_COMBINE_ALPHA 0x8572 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#define GL_COMPATIBLE_SUBROUTINES 0x8E4B -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_R11_EAC_OES 0x9270 -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_RG 0x8226 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_RG11_EAC_OES 0x9272 -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_RGB8_ETC2_OES 0x9274 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276 -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278 -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 -#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 -#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 -#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 -#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_SIGNED_R11_EAC_OES 0x9271 -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_COMPRESSED_SIGNED_RG11_EAC_OES 0x9273 -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES 0x9279 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_SRGB8_ETC2_OES 0x9275 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 -#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1 -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 -#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#define GL_COMPUTE_PROGRAM_NV 0x90FB -#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC -#define GL_COMPUTE_SHADER 0x91B9 -#define GL_COMPUTE_SHADER_BIT 0x00000020 -#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 -#define GL_COMPUTE_SUBROUTINE 0x92ED -#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 -#define GL_COMPUTE_TEXTURE 0x82A0 -#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_CONDITION_SATISFIED 0x911C -#define GL_CONDITION_SATISFIED_APPLE 0x911C -#define GL_CONFORMANT_NV 0x9374 -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_CONJOINT_NV 0x9284 -#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_CONSTANT 0x8576 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_CONSTANT_ARB 0x8576 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_CONSTANT_BORDER 0x8151 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_CONSTANT_COLOR 0x8001 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_CONSTANT_EXT 0x8576 -#define GL_CONSTANT_NV 0x8576 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_FLAGS 0x821E -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_CONTEXT_LOST 0x0507 -#define GL_CONTEXT_LOST_KHR 0x0507 -#define GL_CONTEXT_LOST_WEBGL 0x9242 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC -#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB -#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 -#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 -#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3 -#define GL_CONTINUOUS_AMD 0x9007 -#define GL_CONTRAST_NV 0x92A1 -#define GL_CONVEX_HULL_NV 0x908B -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_2_ATI 0x8943 -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_COORD_REPLACE 0x8862 -#define GL_COORD_REPLACE_ARB 0x8862 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_COORD_REPLACE_OES 0x8862 -#define GL_COPY 0x1503 -#define GL_COPY_INVERTED 0x150C -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_READ_BUFFER_NV 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 -#define GL_COPY_WRITE_BUFFER_NV 0x8F37 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 -#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 -#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 -#define GL_COVERAGE_BUFFERS_NV 0x8ED3 -#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 -#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 -#define GL_COVERAGE_COMPONENT_NV 0x8ED0 -#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 -#define GL_COVERAGE_MODULATION_NV 0x9332 -#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 -#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 -#define GL_COVERAGE_SAMPLES_NV 0x8ED4 -#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_CUBIC_EXT 0x8334 -#define GL_CUBIC_HP 0x815F -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_CULL_MODES_NV 0x86E0 -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_IBM 103050 -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_CURRENT_BIT 0x00000001 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843 -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_CURRENT_QUERY 0x8865 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_CURRENT_QUERY_EXT 0x8865 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_CW 0x0900 -#define GL_DARKEN_KHR 0x9297 -#define GL_DARKEN_NV 0x9297 -#define GL_DATA_BUFFER_AMD 0x9151 -#define GL_DEBUG_ASSERT_MESA 0x875B -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 -#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 -#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F -#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B -#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 -#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D -#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E -#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C -#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 -#define GL_DEBUG_OBJECT_MESA 0x8759 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_DEBUG_OUTPUT_KHR 0x92E0 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 -#define GL_DEBUG_PRINT_MESA 0x875A -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 -#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_API_KHR 0x8246 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_ERROR_KHR 0x824C -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E -#define GL_DECAL 0x2101 -#define GL_DECODE_EXT 0x8A49 -#define GL_DECR 0x1E03 -#define GL_DECR_WRAP 0x8508 -#define GL_DECR_WRAP_EXT 0x8508 -#define GL_DECR_WRAP_OES 0x8508 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_DELETE_STATUS 0x8B80 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DEPTH 0x1801 -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_DEPTH24_STENCIL8_OES 0x88F0 -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_DEPTH_ATTACHMENT_OES 0x8D00 -#define GL_DEPTH_BIAS 0x0D1F -#define GL_DEPTH_BITS 0x0D56 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 -#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 -#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 -#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 -#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 -#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 -#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 -#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -#define GL_DEPTH_CLAMP 0x864F -#define GL_DEPTH_CLAMP_FAR_AMD 0x901F -#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E -#define GL_DEPTH_CLAMP_NV 0x864F -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C -#define GL_DEPTH_COMPONENT16_OES 0x81A5 -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT24_OES 0x81A6 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_DEPTH_COMPONENT32_OES 0x81A7 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#define GL_DEPTH_COMPONENTS 0x8284 -#define GL_DEPTH_EXT 0x1801 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 -#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 -#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_RENDERABLE 0x8287 -#define GL_DEPTH_SAMPLES_NV 0x932D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_DEPTH_STENCIL_MESA 0x8750 -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DIFFERENCE_KHR 0x929E -#define GL_DIFFERENCE_NV 0x929E -#define GL_DIFFUSE 0x1201 -#define GL_DISCARD_ATI 0x8763 -#define GL_DISCARD_NV 0x8530 -#define GL_DISCRETE_AMD 0x9006 -#define GL_DISJOINT_NV 0x9283 -#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE -#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_DISPLAY_LIST 0x82E7 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -#define GL_DITHER 0x0BD0 -#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 -#define GL_DOMAIN 0x0A02 -#define GL_DONT_CARE 0x1100 -#define GL_DOT2_ADD_ATI 0x896C -#define GL_DOT3_ATI 0x8966 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_DOT3_RGBA_ARB 0x86AF -#define GL_DOT3_RGBA_EXT 0x8741 -#define GL_DOT3_RGBA_IMG 0x86AF -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT4_ATI 0x8967 -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_DOUBLE 0x140A -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_DOUBLE_EXT 0x140A -#define GL_DOUBLE_MAT2 0x8F46 -#define GL_DOUBLE_MAT2_EXT 0x8F46 -#define GL_DOUBLE_MAT2x3 0x8F49 -#define GL_DOUBLE_MAT2x3_EXT 0x8F49 -#define GL_DOUBLE_MAT2x4 0x8F4A -#define GL_DOUBLE_MAT2x4_EXT 0x8F4A -#define GL_DOUBLE_MAT3 0x8F47 -#define GL_DOUBLE_MAT3_EXT 0x8F47 -#define GL_DOUBLE_MAT3x2 0x8F4B -#define GL_DOUBLE_MAT3x2_EXT 0x8F4B -#define GL_DOUBLE_MAT3x4 0x8F4C -#define GL_DOUBLE_MAT3x4_EXT 0x8F4C -#define GL_DOUBLE_MAT4 0x8F48 -#define GL_DOUBLE_MAT4_EXT 0x8F48 -#define GL_DOUBLE_MAT4x2 0x8F4D -#define GL_DOUBLE_MAT4x2_EXT 0x8F4D -#define GL_DOUBLE_MAT4x3 0x8F4E -#define GL_DOUBLE_MAT4x3_EXT 0x8F4E -#define GL_DOUBLE_VEC2 0x8FFC -#define GL_DOUBLE_VEC2_EXT 0x8FFC -#define GL_DOUBLE_VEC3 0x8FFD -#define GL_DOUBLE_VEC3_EXT 0x8FFD -#define GL_DOUBLE_VEC4 0x8FFE -#define GL_DOUBLE_VEC4_EXT 0x8FFE -#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 -#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 -#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER0_EXT 0x8825 -#define GL_DRAW_BUFFER0_NV 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER10_EXT 0x882F -#define GL_DRAW_BUFFER10_NV 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER11_EXT 0x8830 -#define GL_DRAW_BUFFER11_NV 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER12_EXT 0x8831 -#define GL_DRAW_BUFFER12_NV 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER13_EXT 0x8832 -#define GL_DRAW_BUFFER13_NV 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER14_EXT 0x8833 -#define GL_DRAW_BUFFER14_NV 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_DRAW_BUFFER15_ARB 0x8834 -#define GL_DRAW_BUFFER15_ATI 0x8834 -#define GL_DRAW_BUFFER15_EXT 0x8834 -#define GL_DRAW_BUFFER15_NV 0x8834 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER1_EXT 0x8826 -#define GL_DRAW_BUFFER1_NV 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER2_EXT 0x8827 -#define GL_DRAW_BUFFER2_NV 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER3_EXT 0x8828 -#define GL_DRAW_BUFFER3_NV 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER4_EXT 0x8829 -#define GL_DRAW_BUFFER4_NV 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER5_EXT 0x882A -#define GL_DRAW_BUFFER5_NV 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER6_EXT 0x882B -#define GL_DRAW_BUFFER6_NV 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER7_EXT 0x882C -#define GL_DRAW_BUFFER7_NV 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER8_EXT 0x882D -#define GL_DRAW_BUFFER8_NV 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER9_EXT 0x882E -#define GL_DRAW_BUFFER9_NV 0x882E -#define GL_DRAW_BUFFER_EXT 0x0C01 -#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 -#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 -#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 -#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 -#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 -#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_DSDT_NV 0x86F5 -#define GL_DST_ALPHA 0x0304 -#define GL_DST_ATOP_NV 0x928F -#define GL_DST_COLOR 0x0306 -#define GL_DST_IN_NV 0x928B -#define GL_DST_NV 0x9287 -#define GL_DST_OUT_NV 0x928D -#define GL_DST_OVER_NV 0x9289 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_BIAS_NV 0x8717 -#define GL_DT_SCALE_NV 0x8711 -#define GL_DU8DV8_ATI 0x877A -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_DUDV_ATI 0x8779 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_DYNAMIC_COPY_ARB 0x88EA -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_STORAGE_BIT 0x0100 -#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_EDGE_FLAG 0x0B43 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 -#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 -#define GL_ELEMENT_ARRAY_APPLE 0x8A0C -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_MAP_NV 0x855F -#define GL_EMISSION 0x1600 -#define GL_ENABLE_BIT 0x00002000 -#define GL_EQUAL 0x0202 -#define GL_EQUIV 0x1509 -#define GL_ETC1_RGB8_OES 0x8D64 -#define GL_ETC1_SRGB8_NV 0x88EE -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_BIT 0x00010000 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_EXCLUSION_NV 0x92A0 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXTENSIONS 0x1F03 -#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_EYE_LINEAR 0x2400 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_EYE_PLANE 0x2502 -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_EYE_RADIAL_NV 0x855B -#define GL_E_TIMES_F_NV 0x8531 -#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07 -#define GL_FACTOR_MAX_AMD 0x901D -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FAILURE_NV 0x9030 -#define GL_FALSE 0 -#define GL_FASTEST 0x1101 -#define GL_FEEDBACK 0x1C01 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_FENCE_APPLE 0x8A0B -#define GL_FENCE_CONDITION_NV 0x84F4 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 -#define GL_FIELDS_NV 0x8E27 -#define GL_FIELD_LOWER_NV 0x9023 -#define GL_FIELD_UPPER_NV 0x9022 -#define GL_FILE_NAME_NV 0x9074 -#define GL_FILL 0x1B02 -#define GL_FILL_NV 0x1B02 -#define GL_FILL_RECTANGLE_NV 0x933C -#define GL_FILTER 0x829A -#define GL_FILTER4_SGIS 0x8146 -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D -#define GL_FIXED 0x140C -#define GL_FIXED_OES 0x140C -#define GL_FIXED_ONLY 0x891D -#define GL_FIXED_ONLY_ARB 0x891D -#define GL_FLAT 0x1D00 -#define GL_FLOAT 0x1406 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x3_NV 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT2x4_NV 0x8B66 -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x2_NV 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT3x4_NV 0x8B68 -#define GL_FLOAT_MAT4 0x8B5C -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x2_NV 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_FLOAT_MAT4x3_NV 0x8B6A -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_FOG 0x0B60 -#define GL_FOG_BIT 0x00000080 -#define GL_FOG_COLOR 0x0B66 -#define GL_FOG_COORD 0x8451 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_FOG_END 0x0B64 -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_HINT 0x0C54 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#define GL_FOG_START 0x0B63 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FRACTIONAL_EVEN 0x8E7C -#define GL_FRACTIONAL_EVEN_EXT 0x8E7C -#define GL_FRACTIONAL_EVEN_OES 0x8E7C -#define GL_FRACTIONAL_ODD 0x8E7B -#define GL_FRACTIONAL_ODD_EXT 0x8E7B -#define GL_FRACTIONAL_ODD_OES 0x8E7B -#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314 -#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315 -#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313 -#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08 -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE -#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_FRAGMENT_INPUT_NV 0x936D -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3 -#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2 -#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1 -#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B -#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 -#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 -#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 -#define GL_FRAGMENT_SUBROUTINE 0x92EC -#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 -#define GL_FRAGMENT_TEXTURE 0x829F -#define GL_FRAMEBUFFER 0x8D40 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6 -#define GL_FRAMEBUFFER_BLEND 0x828B -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 -#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 -#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 -#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC -#define GL_FRAMEBUFFER_OES 0x8D40 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 -#define GL_FRAMEBUFFER_RENDERABLE 0x8289 -#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAME_NV 0x8E26 -#define GL_FRONT 0x0404 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_FRONT_FACE 0x0B46 -#define GL_FRONT_FACE_COMMAND_NV 0x0012 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_FULL_SUPPORT 0x82B7 -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_FUNC_ADD_OES 0x8006 -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_SUBTRACT_OES 0x800A -#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 -#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 -#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 -#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 -#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 -#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F -#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F -#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F -#define GL_GEOMETRY_SHADER_OES 0x8DD9 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 -#define GL_GEOMETRY_SUBROUTINE 0x92EB -#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 -#define GL_GEOMETRY_TEXTURE 0x829E -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEQUAL 0x0206 -#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 -#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GPU_ADDRESS_NV 0x8F34 -#define GL_GPU_DISJOINT_EXT 0x8FBB -#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 -#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 -#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B -#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A -#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 -#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 -#define GL_GREATER 0x0204 -#define GL_GREEN 0x1904 -#define GL_GREEN_BIAS 0x0D19 -#define GL_GREEN_BITS 0x0D53 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_GREEN_NV 0x1904 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GUILTY_CONTEXT_RESET 0x8253 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 -#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253 -#define GL_HALF_APPLE 0x140B -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_HALF_FLOAT 0x140B -#define GL_HALF_FLOAT_ARB 0x140B -#define GL_HALF_FLOAT_NV 0x140B -#define GL_HALF_FLOAT_OES 0x8D61 -#define GL_HARDLIGHT_KHR 0x929B -#define GL_HARDLIGHT_NV 0x929B -#define GL_HARDMIX_NV 0x92A9 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_HIGH_INT 0x8DF5 -#define GL_HILO16_NV 0x86F8 -#define GL_HILO8_NV 0x885E -#define GL_HILO_NV 0x86F4 -#define GL_HINT_BIT 0x00008000 -#define GL_HISTOGRAM 0x8024 -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_SINK 0x802D -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HI_BIAS_NV 0x8714 -#define GL_HI_SCALE_NV 0x870E -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_COLOR_NV 0x92AF -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_HUE_NV 0x92AD -#define GL_HSL_LUMINOSITY_KHR 0x92B0 -#define GL_HSL_LUMINOSITY_NV 0x92B0 -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_SATURATION_NV 0x92AE -#define GL_IDENTITY_NV 0x862A -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_IMAGE_1D 0x904C -#define GL_IMAGE_1D_ARRAY 0x9052 -#define GL_IMAGE_1D_ARRAY_EXT 0x9052 -#define GL_IMAGE_1D_EXT 0x904C -#define GL_IMAGE_2D 0x904D -#define GL_IMAGE_2D_ARRAY 0x9053 -#define GL_IMAGE_2D_ARRAY_EXT 0x9053 -#define GL_IMAGE_2D_EXT 0x904D -#define GL_IMAGE_2D_MULTISAMPLE 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 -#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 -#define GL_IMAGE_2D_RECT 0x904F -#define GL_IMAGE_2D_RECT_EXT 0x904F -#define GL_IMAGE_3D 0x904E -#define GL_IMAGE_3D_EXT 0x904E -#define GL_IMAGE_BINDING_ACCESS 0x8F3E -#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E -#define GL_IMAGE_BINDING_FORMAT 0x906E -#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E -#define GL_IMAGE_BINDING_LAYER 0x8F3D -#define GL_IMAGE_BINDING_LAYERED 0x8F3C -#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C -#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D -#define GL_IMAGE_BINDING_LEVEL 0x8F3B -#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B -#define GL_IMAGE_BINDING_NAME 0x8F3A -#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A -#define GL_IMAGE_BUFFER 0x9051 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_IMAGE_BUFFER_OES 0x9051 -#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 -#define GL_IMAGE_CLASS_11_11_10 0x82C2 -#define GL_IMAGE_CLASS_1_X_16 0x82BE -#define GL_IMAGE_CLASS_1_X_32 0x82BB -#define GL_IMAGE_CLASS_1_X_8 0x82C1 -#define GL_IMAGE_CLASS_2_X_16 0x82BD -#define GL_IMAGE_CLASS_2_X_32 0x82BA -#define GL_IMAGE_CLASS_2_X_8 0x82C0 -#define GL_IMAGE_CLASS_4_X_16 0x82BC -#define GL_IMAGE_CLASS_4_X_32 0x82B9 -#define GL_IMAGE_CLASS_4_X_8 0x82BF -#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 -#define GL_IMAGE_CUBE 0x9050 -#define GL_IMAGE_CUBE_EXT 0x9050 -#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 -#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_PIXEL_FORMAT 0x82A9 -#define GL_IMAGE_PIXEL_TYPE 0x82AA -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TEXEL_SIZE 0x82A7 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_INCR 0x1E02 -#define GL_INCR_WRAP 0x8507 -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_INCR_WRAP_OES 0x8507 -#define GL_INDEX 0x8222 -#define GL_INDEX_ARRAY 0x8077 -#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_BITS 0x0D51 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MODE 0x0C30 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_INNOCENT_CONTEXT_RESET 0x8254 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 -#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254 -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -#define GL_INT 0x1404 -#define GL_INT16_NV 0x8FE4 -#define GL_INT16_VEC2_NV 0x8FE5 -#define GL_INT16_VEC3_NV 0x8FE6 -#define GL_INT16_VEC4_NV 0x8FE7 -#define GL_INT64_NV 0x140E -#define GL_INT64_VEC2_NV 0x8FE9 -#define GL_INT64_VEC3_NV 0x8FEA -#define GL_INT64_VEC4_NV 0x8FEB -#define GL_INT8_NV 0x8FE0 -#define GL_INT8_VEC2_NV 0x8FE1 -#define GL_INT8_VEC3_NV 0x8FE2 -#define GL_INT8_VEC4_NV 0x8FE3 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16 0x804D -#define GL_INTENSITY16F_ARB 0x881D -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_INTENSITY16_EXT 0x804D -#define GL_INTENSITY16_SNORM 0x901B -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY8_SNORM 0x9017 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_INTENSITY_SNORM 0x9013 -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_INGR 0x8568 -#define GL_INTERLACE_READ_OML 0x8981 -#define GL_INTERLACE_SGIX 0x8094 -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 -#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B -#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 -#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A -#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 -#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C -#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 -#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 -#define GL_INTERNALFORMAT_PREFERRED 0x8270 -#define GL_INTERNALFORMAT_RED_SIZE 0x8271 -#define GL_INTERNALFORMAT_RED_TYPE 0x8278 -#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 -#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 -#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D -#define GL_INTERNALFORMAT_SUPPORTED 0x826F -#define GL_INTERPOLATE 0x8575 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_INT_10_10_10_2_OES 0x8DF7 -#define GL_INT_2_10_10_10_REV 0x8D9F -#define GL_INT_IMAGE_1D 0x9057 -#define GL_INT_IMAGE_1D_ARRAY 0x905D -#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D -#define GL_INT_IMAGE_1D_EXT 0x9057 -#define GL_INT_IMAGE_2D 0x9058 -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E -#define GL_INT_IMAGE_2D_EXT 0x9058 -#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 -#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 -#define GL_INT_IMAGE_2D_RECT 0x905A -#define GL_INT_IMAGE_2D_RECT_EXT 0x905A -#define GL_INT_IMAGE_3D 0x9059 -#define GL_INT_IMAGE_3D_EXT 0x9059 -#define GL_INT_IMAGE_BUFFER 0x905C -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_INT_IMAGE_BUFFER_OES 0x905C -#define GL_INT_IMAGE_CUBE 0x905B -#define GL_INT_IMAGE_CUBE_EXT 0x905B -#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_INVALID_OPERATION 0x0502 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_INVARIANT_EXT 0x87C2 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVERSE_NV 0x862B -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_INVERT 0x150A -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#define GL_INVERT_OVG_NV 0x92B4 -#define GL_INVERT_RGB_NV 0x92A3 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#define GL_ISOLINES 0x8E7A -#define GL_ISOLINES_EXT 0x8E7A -#define GL_ISOLINES_OES 0x8E7A -#define GL_IS_PER_PATCH 0x92E7 -#define GL_IS_PER_PATCH_EXT 0x92E7 -#define GL_IS_PER_PATCH_OES 0x92E7 -#define GL_IS_ROW_MAJOR 0x9300 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_KEEP 0x1E00 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E -#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 -#define GL_LAYER_NV 0x8DAA -#define GL_LAYER_PROVOKING_VERTEX 0x825E -#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E -#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E -#define GL_LAYOUT_DEFAULT_INTEL 0 -#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 -#define GL_LAYOUT_LINEAR_INTEL 1 -#define GL_LEFT 0x0406 -#define GL_LEQUAL 0x0203 -#define GL_LERP_ATI 0x8969 -#define GL_LESS 0x0201 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_LIGHTEN_NV 0x9298 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LINE 0x1B01 -#define GL_LINEAR 0x2601 -#define GL_LINEARBURN_NV 0x92A5 -#define GL_LINEARDODGE_NV 0x92A4 -#define GL_LINEARLIGHT_NV 0x92A7 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINES 0x0001 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINES_ADJACENCY_ARB 0x000A -#define GL_LINES_ADJACENCY_EXT 0x000A -#define GL_LINES_ADJACENCY_OES 0x000A -#define GL_LINE_BIT 0x00000004 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_NV 0x1B01 -#define GL_LINE_QUALITY_HINT_SGIX 0x835B -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LINE_STRIP 0x0003 -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B -#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -#define GL_LINE_STRIP_ADJACENCY_OES 0x000B -#define GL_LINE_TOKEN 0x0702 -#define GL_LINE_TO_NV 0x04 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_COMMAND_NV 0x000D -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINK_STATUS 0x8B82 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_BIT 0x00020000 -#define GL_LIST_INDEX 0x0B33 -#define GL_LIST_MODE 0x0B30 -#define GL_LIST_PRIORITY_SGIX 0x8182 -#define GL_LOAD 0x0101 -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_EXT 0x87C4 -#define GL_LOCATION 0x930E -#define GL_LOCATION_COMPONENT 0x934A -#define GL_LOCATION_INDEX 0x930F -#define GL_LOGIC_OP 0x0BF1 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_LOSE_CONTEXT_ON_RESET 0x8252 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 -#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_LOW_FLOAT 0x8DF0 -#define GL_LOW_INT 0x8DF3 -#define GL_LO_BIAS_NV 0x8715 -#define GL_LO_SCALE_NV 0x870F -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE16F_EXT 0x881E -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE16_SNORM 0x9019 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE32F_EXT 0x8818 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE4_ALPHA4_OES 0x8043 -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE8_ALPHA8_OES 0x8045 -#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE8_OES 0x8040 -#define GL_LUMINANCE8_SNORM 0x9015 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#define GL_LUMINANCE_ALPHA16F_EXT 0x881F -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_LUMINANCE_ALPHA_SNORM 0x9012 -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_SNORM 0x9011 -#define GL_MAD_ATI 0x8968 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_MAJOR_VERSION 0x821B -#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 -#define GL_MALI_SHADER_BINARY_ARM 0x8F60 -#define GL_MANUAL_GENERATE_MIPMAP 0x8294 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP2_BINORMAL_EXT 0x8447 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_MAP_COHERENT_BIT 0x0080 -#define GL_MAP_COHERENT_BIT_EXT 0x0080 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 -#define GL_MAP_PERSISTENT_BIT 0x0040 -#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_READ_BIT_EXT 0x0001 -#define GL_MAP_STENCIL 0x0D11 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_WRITE_BIT_EXT 0x0002 -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX7_NV 0x8637 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX_EXT 0x87C0 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E -#define GL_MATRIX_INDEX_ARRAY_OES 0x8844 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MATRIX_PALETTE_OES 0x8840 -#define GL_MATRIX_STRIDE 0x92FF -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_MAX 0x8008 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC -#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_CLIP_PLANES_IMG 0x0D32 -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 -#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA -#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 -#define GL_MAX_COMBINED_DIMENSIONS 0x8282 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 -#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 -#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 -#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 -#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 -#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB -#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF -#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB -#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 -#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC -#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB -#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 -#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 -#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 -#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE -#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB -#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C -#define GL_MAX_CULL_DISTANCES 0x82F9 -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 -#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 -#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -#define GL_MAX_DEPTH 0x8280 -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 -#define GL_MAX_DRAW_BUFFERS_NV 0x8824 -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_EXT 0x8008 -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 -#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 -#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 -#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 -#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 -#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 -#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF -#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD -#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 -#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 -#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_HEIGHT 0x827F -#define GL_MAX_IMAGE_SAMPLES 0x906D -#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D -#define GL_MAX_IMAGE_UNITS 0x8F38 -#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 -#define GL_MAX_LAYERS 0x8281 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 -#define GL_MAX_NAME_LENGTH 0x92F6 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 -#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_MAX_PALETTE_MATRICES_OES 0x8842 -#define GL_MAX_PATCH_VERTICES 0x8E7D -#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D -#define GL_MAX_PATCH_VERTICES_OES 0x8E7D -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 -#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_MAX_SAMPLES_ANGLE 0x8D57 -#define GL_MAX_SAMPLES_APPLE 0x8D57 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#define GL_MAX_SAMPLES_IMG 0x9135 -#define GL_MAX_SAMPLES_NV 0x8D57 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 -#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 -#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 -#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 -#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE -#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 -#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A -#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A -#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 -#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 -#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 -#define GL_MAX_SUBROUTINES 0x8DE7 -#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD -#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB -#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 -#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE -#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC -#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 -#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 -#define GL_MAX_TESS_GEN_LEVEL 0x8E7E -#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E -#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E -#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 -#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 -#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_LOCATIONS 0x826E -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 -#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA -#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 -#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_STREAMS 0x8E71 -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_MAX_VERTEX_UNITS_OES 0x86A4 -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VIEWPORTS 0x825B -#define GL_MAX_VIEWPORTS_NV 0x825B -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MAX_WIDTH 0x827E -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_MIN 0x8007 -#define GL_MINMAX 0x802E -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_MINOR_VERSION 0x821C -#define GL_MINUS_CLAMPED_NV 0x92B3 -#define GL_MINUS_NV 0x929F -#define GL_MIN_EXT 0x8007 -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B -#define GL_MIN_LOD_WARNING_AMD 0x919C -#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E -#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 -#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 -#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 -#define GL_MIN_SPARSE_LEVEL_AMD 0x919B -#define GL_MIPMAP 0x8293 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#define GL_MIRRORED_REPEAT_OES 0x8370 -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F -#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 -#define GL_MODELVIEW 0x1700 -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW0_EXT 0x1700 -#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 -#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW1_EXT 0x850A -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_MODULATE 0x2100 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_COLOR_IMG 0x8C04 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_MOVE_TO_NV 0x02 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOV_ATI 0x8961 -#define GL_MULT 0x0103 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_MULTIPLY_NV 0x9294 -#define GL_MULTISAMPLE 0x809D -#define GL_MULTISAMPLES_NV 0x9371 -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 -#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 -#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 -#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 -#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 -#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 -#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 -#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_MULTIVIEW_EXT 0x90F1 -#define GL_MUL_ATI 0x8964 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_N3F_V3F 0x2A25 -#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 -#define GL_NAMED_STRING_TYPE_ARB 0x8DEA -#define GL_NAME_LENGTH 0x92F9 -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_NAND 0x150E -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NEAREST 0x2600 -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NEGATIVE_ONE_TO_ONE 0x935E -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEVER 0x0200 -#define GL_NEXT_BUFFER_NV -2 -#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 -#define GL_NICEST 0x1102 -#define GL_NONE 0 -#define GL_NONE_OES 0 -#define GL_NOOP 0x1505 -#define GL_NOP_COMMAND_NV 0x0001 -#define GL_NOR 0x1508 -#define GL_NORMALIZE 0x0BA1 -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_NORMAL_MAP_OES 0x8511 -#define GL_NOTEQUAL 0x0205 -#define GL_NO_ERROR 0 -#define GL_NO_RESET_NOTIFICATION 0x8261 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 -#define GL_NO_RESET_NOTIFICATION_KHR 0x8261 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_NUM_EXTENSIONS 0x821D -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE -#define GL_NUM_SAMPLE_COUNTS 0x9380 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 -#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA -#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA -#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 -#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 -#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_PLANE 0x2501 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_OBJECT_TYPE 0x9112 -#define GL_OBJECT_TYPE_APPLE 0x9112 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#define GL_OFFSET 0x92FC -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_ONE 1 -#define GL_ONE_EXT 0x87DE -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_OPERAND2_ALPHA_EXT 0x859A -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND3_ALPHA_NV 0x859B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_MOV_EXT 0x8799 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_SUB_EXT 0x8796 -#define GL_OR 0x1507 -#define GL_ORDER 0x0A01 -#define GL_OR_INVERTED 0x150D -#define GL_OR_REVERSE 0x150B -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_OVERLAY_KHR 0x9296 -#define GL_OVERLAY_NV 0x9296 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D -#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C -#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E -#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B -#define GL_PACK_COMPRESSED_SIZE_SGIX 0x831C -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_PACK_INVERT_MESA 0x8758 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_PACK_RESAMPLE_SGIX 0x842E -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#define GL_PACK_ROW_BYTES_APPLE 0x8A15 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_PARAMETER_BUFFER_ARB 0x80EE -#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF -#define GL_PARTIAL_SUCCESS_NV 0x902E -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_PATCHES 0x000E -#define GL_PATCHES_EXT 0x000E -#define GL_PATCHES_OES 0x000E -#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 -#define GL_PATCH_DEFAULT_INNER_LEVEL_EXT 0x8E73 -#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 -#define GL_PATCH_DEFAULT_OUTER_LEVEL_EXT 0x8E74 -#define GL_PATCH_VERTICES 0x8E72 -#define GL_PATCH_VERTICES_EXT 0x8E72 -#define GL_PATCH_VERTICES_OES 0x8E72 -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFORMANCE_MONITOR_AMD 0x9152 -#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC -#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB -#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA -#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 -#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 -#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF -#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 -#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 -#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 -#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE -#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 -#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 -#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 -#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 -#define GL_PERFQUERY_FLUSH_INTEL 0x83FA -#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 -#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 -#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD -#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 -#define GL_PERFQUERY_WAIT_INTEL 0x83FB -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_PERTURB_EXT 0x85AE -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -#define GL_PHONG_HINT_WIN 0x80EB -#define GL_PHONG_WIN 0x80EA -#define GL_PINLIGHT_NV 0x92A8 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 -#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A -#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 -#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 -#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 -#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 -#define GL_PLUS_CLAMPED_NV 0x92B1 -#define GL_PLUS_DARKER_NV 0x9292 -#define GL_PLUS_NV 0x9291 -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_POINT 0x1B00 -#define GL_POINTS 0x0000 -#define GL_POINT_BIT 0x00000002 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_POINT_NV 0x1B00 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F -#define GL_POINT_SIZE_ARRAY_OES 0x8B9C -#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C -#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B -#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_POINT_SPRITE 0x8861 -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_POINT_SPRITE_OES 0x8861 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -#define GL_POINT_TOKEN 0x0701 -#define GL_POLYGON 0x0009 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_MODE_NV 0x0B40 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B -#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_POSITION 0x1203 -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_PRESENT_DURATION_NV 0x8E2B -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESERVE_ATI 0x8762 -#define GL_PREVIOUS 0x8578 -#define GL_PREVIOUS_ARB 0x8578 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_PRIMITIVES_GENERATED_OES 0x8C87 -#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF -#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE -#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 -#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PROGRAM 0x82E2 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_BINARY_ANGLE 0x93A6 -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_INPUT 0x92E3 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_PROGRAM_KHR 0x82E2 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_PROGRAM_OUTPUT 0x92E4 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A -#define GL_PROGRAM_PIPELINE_KHR 0x82E4 -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_PROGRAM_SEPARABLE_EXT 0x8258 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_PROJECTION 0x1701 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_PROVOKING_VERTEX_EXT 0x8E4F -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_PURGEABLE_APPLE 0x8A1D -#define GL_Q 0x2003 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_QUADS 0x0007 -#define GL_QUADS_EXT 0x0007 -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C -#define GL_QUADS_OES 0x0007 -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_QUAD_STRIP 0x0008 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_QUERY 0x82E3 -#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF -#define GL_QUERY_BUFFER 0x9192 -#define GL_QUERY_BUFFER_AMD 0x9192 -#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 -#define GL_QUERY_BUFFER_BINDING 0x9193 -#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_QUERY_COUNTER_BITS_EXT 0x8864 -#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 -#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 -#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 -#define GL_QUERY_KHR 0x82E3 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_OBJECT_AMD 0x9153 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 -#define GL_QUERY_RESULT_EXT 0x8866 -#define GL_QUERY_RESULT_NO_WAIT 0x9194 -#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 -#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 -#define GL_QUERY_TARGET 0x82EA -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_WAIT_INVERTED 0x8E17 -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_R 0x2002 -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_R11F_G11F_B10F_APPLE 0x8C3A -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_R16 0x822A -#define GL_R16F 0x822D -#define GL_R16F_EXT 0x822D -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R16_EXT 0x822A -#define GL_R16_SNORM 0x8F98 -#define GL_R16_SNORM_EXT 0x8F98 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R32F 0x822E -#define GL_R32F_EXT 0x822E -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_R3_G3_B2 0x2A10 -#define GL_R8 0x8229 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R8_EXT 0x8229 -#define GL_R8_SNORM 0x8F94 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A -#define GL_RASTER_MULTISAMPLE_EXT 0x9327 -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#define GL_RASTER_SAMPLES_EXT 0x9328 -#define GL_READ_BUFFER 0x0C02 -#define GL_READ_BUFFER_EXT 0x0C02 -#define GL_READ_BUFFER_NV 0x0C02 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 -#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA -#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_READ_FRAMEBUFFER_NV 0x8CA8 -#define GL_READ_ONLY 0x88B8 -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_READ_PIXELS 0x828C -#define GL_READ_PIXELS_FORMAT 0x828D -#define GL_READ_PIXELS_TYPE 0x828E -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -#define GL_READ_WRITE 0x88BA -#define GL_READ_WRITE_ARB 0x88BA -#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05 -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_RECT_NV 0xF6 -#define GL_RED 0x1903 -#define GL_REDUCE 0x8016 -#define GL_REDUCE_EXT 0x8016 -#define GL_RED_BIAS 0x0D15 -#define GL_RED_BITS 0x0D52 -#define GL_RED_BIT_ATI 0x00000001 -#define GL_RED_EXT 0x1903 -#define GL_RED_INTEGER 0x8D94 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_RED_NV 0x1903 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_SNORM 0x8F90 -#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B -#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A -#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 -#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 -#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 -#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 -#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFLECTION_MAP 0x8512 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_REFLECTION_MAP_NV 0x8512 -#define GL_REFLECTION_MAP_OES 0x8512 -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_2_ATI 0x8923 -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_RELEASED_APPLE 0x8A19 -#define GL_RENDER 0x1C00 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_RENDERBUFFER_BINDING_ANGLE 0x8CA7 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_RENDERBUFFER_BINDING_OES 0x8CA7 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52 -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44 -#define GL_RENDERBUFFER_OES 0x8D41 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB -#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 -#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_WIDTH_OES 0x8D42 -#define GL_RENDERER 0x1F01 -#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 -#define GL_RENDER_MODE 0x0C40 -#define GL_REPEAT 0x2901 -#define GL_REPLACE 0x1E01 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACE_EXT 0x8062 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_REPLACE_VALUE_AMD 0x874B -#define GL_REPLICATE_BORDER 0x8153 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 -#define GL_RESCALE_NORMAL 0x803A -#define GL_RESCALE_NORMAL_EXT 0x803A -#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 -#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_RESTART_SUN 0x0001 -#define GL_RETAINED_APPLE 0x8A1B -#define GL_RETURN 0x0102 -#define GL_RG 0x8227 -#define GL_RG16 0x822C -#define GL_RG16F 0x822F -#define GL_RG16F_EXT 0x822F -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG16_EXT 0x822C -#define GL_RG16_SNORM 0x8F99 -#define GL_RG16_SNORM_EXT 0x8F99 -#define GL_RG32F 0x8230 -#define GL_RG32F_EXT 0x8230 -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_RG8 0x822B -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG8_EXT 0x822B -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB 0x1907 -#define GL_RGB10 0x8052 -#define GL_RGB10_A2 0x8059 -#define GL_RGB10_A2UI 0x906F -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGB16F 0x881B -#define GL_RGB16F_ARB 0x881B -#define GL_RGB16F_EXT 0x881B -#define GL_RGB16I 0x8D89 -#define GL_RGB16I_EXT 0x8D89 -#define GL_RGB16UI 0x8D77 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_RGB16_EXT 0x8054 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGB16_SNORM_EXT 0x8F9A -#define GL_RGB2_EXT 0x804E -#define GL_RGB32F 0x8815 -#define GL_RGB32F_ARB 0x8815 -#define GL_RGB32F_EXT 0x8815 -#define GL_RGB32I 0x8D83 -#define GL_RGB32I_EXT 0x8D83 -#define GL_RGB32UI 0x8D71 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_RGB4 0x804F -#define GL_RGB4_EXT 0x804F -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGB5 0x8050 -#define GL_RGB565 0x8D62 -#define GL_RGB565_OES 0x8D62 -#define GL_RGB5_A1 0x8057 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGB5_A1_OES 0x8057 -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB8I 0x8D8F -#define GL_RGB8I_EXT 0x8D8F -#define GL_RGB8UI 0x8D7D -#define GL_RGB8UI_EXT 0x8D7D -#define GL_RGB8_EXT 0x8051 -#define GL_RGB8_OES 0x8051 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGB9_E5 0x8C3D -#define GL_RGB9_E5_APPLE 0x8C3D -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_RGBA 0x1908 -#define GL_RGBA12 0x805A -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16 0x805B -#define GL_RGBA16F 0x881A -#define GL_RGBA16F_ARB 0x881A -#define GL_RGBA16F_EXT 0x881A -#define GL_RGBA16I 0x8D88 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGBA16UI 0x8D76 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGBA16_EXT 0x805B -#define GL_RGBA16_SNORM 0x8F9B -#define GL_RGBA16_SNORM_EXT 0x8F9B -#define GL_RGBA2 0x8055 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA32F 0x8814 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGBA32F_EXT 0x8814 -#define GL_RGBA32I 0x8D82 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGBA32UI 0x8D70 -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGBA4 0x8056 -#define GL_RGBA4_DXT5_S3TC 0x83A5 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGBA4_OES 0x8056 -#define GL_RGBA4_S3TC 0x83A3 -#define GL_RGBA8 0x8058 -#define GL_RGBA8I 0x8D8E -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGBA8UI 0x8D7C -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGBA8_EXT 0x8058 -#define GL_RGBA8_OES 0x8058 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_RGBA_DXT5_S3TC 0x83A4 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_RGBA_FLOAT_MODE_ATI 0x8820 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -#define GL_RGBA_MODE 0x0C31 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#define GL_RGBA_SNORM 0x8F93 -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_RGB_422_APPLE 0x8A1F -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGB_RAW_422_APPLE 0x8A51 -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB_SCALE 0x8573 -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_RGB_SNORM 0x8F92 -#define GL_RG_EXT 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_RG_SNORM 0x8F91 -#define GL_RIGHT 0x0407 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_ROUND_NV 0x90A4 -#define GL_S 0x2000 -#define GL_SAMPLER 0x82E6 -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_3D_OES 0x8B5F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_BUFFER_OES 0x8DC2 -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 -#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_SAMPLER_KHR 0x82E6 -#define GL_SAMPLER_OBJECT_AMD 0x9155 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLES_PASSED 0x8914 -#define GL_SAMPLES_PASSED_ARB 0x8914 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_LOCATION_NV 0x8E50 -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_SHADING 0x8C36 -#define GL_SAMPLE_SHADING_ARB 0x8C36 -#define GL_SAMPLE_SHADING_OES 0x8C36 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_SCALAR_EXT 0x87BE -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA -#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCISSOR_BIT 0x00080000 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_COMMAND_NV 0x0011 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_SCREEN_KHR 0x9295 -#define GL_SCREEN_NV 0x9295 -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_SELECT 0x1C02 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_SEPARABLE_2D 0x8012 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#define GL_SET 0x150F -#define GL_SET_AMD 0x874A -#define GL_SGX_BINARY_IMG 0x8C0A -#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 -#define GL_SHADER 0x82E1 -#define GL_SHADER_BINARY_DMP 0x9250 -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_SHADER_BINARY_VIV 0x8FC4 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 -#define GL_SHADER_IMAGE_ATOMIC 0x82A6 -#define GL_SHADER_IMAGE_LOAD 0x82A4 -#define GL_SHADER_IMAGE_STORE 0x82A5 -#define GL_SHADER_INCLUDE_ARB 0x8DAE -#define GL_SHADER_KHR 0x82E1 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 -#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF -#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 -#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_SHADER_TYPE 0x8B4F -#define GL_SHADE_MODEL 0x0B54 -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_SHARED_EDGE_NV 0xC0 -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -#define GL_SHININESS 0x1601 -#define GL_SHORT 0x1402 -#define GL_SIGNALED 0x9119 -#define GL_SIGNALED_APPLE 0x9119 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC -#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD -#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SKIP_COMPONENTS1_NV -6 -#define GL_SKIP_COMPONENTS2_NV -5 -#define GL_SKIP_COMPONENTS3_NV -4 -#define GL_SKIP_COMPONENTS4_NV -3 -#define GL_SKIP_DECODE_EXT 0x8A4A -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_SLICE_ACCUM_SUN 0x85CC -#define GL_SLIM10U_SGIX 0x831E -#define GL_SLIM12S_SGIX 0x831F -#define GL_SLIM8U_SGIX 0x831D -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_SLUMINANCE8_NV 0x8C47 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE_ALPHA_NV 0x8C44 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE_NV 0x8C46 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 -#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 -#define GL_SMOOTH 0x1D01 -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_SM_COUNT_NV 0x933B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_SOFTLIGHT_NV 0x929C -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SPARE0_NV 0x852E -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_SPARE1_NV 0x852F -#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 -#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 -#define GL_SPECULAR 0x1202 -#define GL_SPHERE_MAP 0x2402 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SQUARE_NV 0x90A3 -#define GL_SR8_EXT 0x8FBD -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_ALPHA 0x8589 -#define GL_SRC1_COLOR 0x88F9 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_ALPHA 0x858A -#define GL_SRC2_RGB 0x8582 -#define GL_SRC_ALPHA 0x0302 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_SRC_ATOP_NV 0x928E -#define GL_SRC_COLOR 0x0300 -#define GL_SRC_IN_NV 0x928A -#define GL_SRC_NV 0x9286 -#define GL_SRC_OUT_NV 0x928C -#define GL_SRC_OVER_NV 0x9288 -#define GL_SRG8_EXT 0x8FBE -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB8_NV 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB_DECODE_ARB 0x8299 -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB_READ 0x8297 -#define GL_SRGB_WRITE 0x8298 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_OVERFLOW_KHR 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_STACK_UNDERFLOW_KHR 0x0504 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_STATE_RESTORE 0x8BDC -#define GL_STATIC_ATI 0x8760 -#define GL_STATIC_COPY 0x88E6 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 -#define GL_STENCIL 0x1802 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_STENCIL_ATTACHMENT_OES 0x8D20 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_STENCIL_BITS 0x0D57 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 -#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 -#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 -#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 -#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 -#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 -#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 -#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_COMPONENTS 0x8285 -#define GL_STENCIL_EXT 0x1802 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_INDEX 0x1901 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX1_OES 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX4_OES 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX8_OES 0x8D48 -#define GL_STENCIL_INDEX_OES 0x1901 -#define GL_STENCIL_OP_VALUE_AMD 0x874C -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_REF_COMMAND_NV 0x000C -#define GL_STENCIL_RENDERABLE 0x8288 -#define GL_STENCIL_SAMPLES_NV 0x932E -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STEREO 0x0C33 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_CLIENT_APPLE 0x85B4 -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -#define GL_STORAGE_SHARED_APPLE 0x85BF -#define GL_STREAM_COPY 0x88E2 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_RASTERIZATION_AMD 0x91A0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 -#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F -#define GL_SUBTRACT 0x84E7 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_SUB_ATI 0x8965 -#define GL_SUCCESS_NV 0x902F -#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 -#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 -#define GL_SURFACE_MAPPED_NV 0x8700 -#define GL_SURFACE_REGISTERED_NV 0x86FD -#define GL_SURFACE_STATE_NV 0x86EB -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SYNC_CL_EVENT_ARB 0x8240 -#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_CONDITION_APPLE 0x9113 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_FENCE_APPLE 0x9116 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FLAGS_APPLE 0x9115 -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 -#define GL_SYNC_OBJECT_APPLE 0x8A53 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_STATUS_APPLE 0x9114 -#define GL_SYNC_X11_FENCE_EXT 0x90E1 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_T 0x2001 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_C4F_N3F_V4F 0x2A2D -#define GL_T4F_V4F 0x2A28 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 -#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 -#define GL_TESS_CONTROL_PROGRAM_NV 0x891E -#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 -#define GL_TESS_CONTROL_SHADER 0x8E88 -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 -#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 -#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 -#define GL_TESS_CONTROL_SHADER_OES 0x8E88 -#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 -#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 -#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF -#define GL_TESS_CONTROL_TEXTURE 0x829C -#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F -#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 -#define GL_TESS_EVALUATION_SHADER 0x8E87 -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 -#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 -#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 -#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 -#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA -#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 -#define GL_TESS_EVALUATION_TEXTURE 0x829D -#define GL_TESS_GEN_MODE 0x8E76 -#define GL_TESS_GEN_MODE_EXT 0x8E76 -#define GL_TESS_GEN_MODE_OES 0x8E76 -#define GL_TESS_GEN_POINT_MODE 0x8E79 -#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 -#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 -#define GL_TESS_GEN_SPACING 0x8E77 -#define GL_TESS_GEN_SPACING_EXT 0x8E77 -#define GL_TESS_GEN_SPACING_OES 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 -#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 -#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_TEXTURE 0x1702 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_TEXTURE31_ARB 0x84DF -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -#define GL_TEXTURE_3D_BINDING_OES 0x806A -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_TEXTURE_3D_OES 0x806F -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06 -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_TEXTURE_BINDING_3D_OES 0x806A -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 -#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 -#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_TEXTURE_BUFFER_BINDING 0x8C2A -#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A -#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -#define GL_TEXTURE_BUFFER_OES 0x8C2A -#define GL_TEXTURE_BUFFER_OFFSET 0x919D -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F -#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F -#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D -#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D -#define GL_TEXTURE_BUFFER_SIZE 0x919E -#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E -#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 -#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 -#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 -#define GL_TEXTURE_CROP_RECT_OES 0x8B9D -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 -#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 -#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 -#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A -#define GL_TEXTURE_CUBE_MAP_OES 0x8513 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519 -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_ENV 0x2300 -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC -#define GL_TEXTURE_GATHER 0x82A2 -#define GL_TEXTURE_GATHER_SHADOW 0x82A3 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_TEXTURE_GEN_MODE_OES 0x2500 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_STR_OES 0x8D60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_IMAGE_FORMAT 0x828F -#define GL_TEXTURE_IMAGE_TYPE 0x8290 -#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F -#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#define GL_TEXTURE_NORMAL_EXT 0x85AF -#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 -#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_SAMPLES_IMG 0x9136 -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_TEXTURE_SHADOW 0x82A1 -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#define GL_TEXTURE_SPARSE_ARB 0x91A6 -#define GL_TEXTURE_SPARSE_EXT 0x91A6 -#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_TARGET 0x1006 -#define GL_TEXTURE_TARGET_QCOM 0x8BDA -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#define GL_TEXTURE_TYPE_QCOM 0x8BD7 -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 -#define GL_TEXTURE_USAGE_ANGLE 0x93A2 -#define GL_TEXTURE_VIEW 0x82B5 -#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD -#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD -#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD -#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB -#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB -#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB -#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE -#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE -#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE -#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC -#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC -#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_TEXTURE_WRAP_R_OES 0x8072 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_TIMEOUT_EXPIRED_APPLE 0x911B -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFF -#define GL_TIMESTAMP 0x8E28 -#define GL_TIMESTAMP_EXT 0x8E28 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIME_ELAPSED_EXT 0x88BF -#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C -#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D -#define GL_TRACE_ALL_BITS_MESA 0xFFFF -#define GL_TRACE_ARRAYS_BIT_MESA 0x0004 -#define GL_TRACE_ERRORS_BIT_MESA 0x0020 -#define GL_TRACE_MASK_MESA 0x8755 -#define GL_TRACE_NAME_MESA 0x8756 -#define GL_TRACE_OPERATIONS_BIT_MESA 0x0001 -#define GL_TRACE_PIXELS_BIT_MESA 0x0010 -#define GL_TRACE_PRIMITIVES_BIT_MESA 0x0002 -#define GL_TRACE_TEXTURES_BIT_MESA 0x0008 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C -#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 -#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED -#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_NV 0x862C -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLES_ADJACENCY_ARB 0x000C -#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -#define GL_TRIANGLES_ADJACENCY_OES 0x000C -#define GL_TRIANGLE_FAN 0x0006 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_TRIANGLE_MESH_SUN 0x8615 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_TRUE 1 -#define GL_TYPE 0x92FA -#define GL_UNCORRELATED_NV 0x9282 -#define GL_UNDEFINED_APPLE 0x8A1C -#define GL_UNDEFINED_VERTEX 0x8260 -#define GL_UNDEFINED_VERTEX_EXT 0x8260 -#define GL_UNDEFINED_VERTEX_OES 0x8260 -#define GL_UNIFORM 0x92E1 -#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 -#define GL_UNIFORM_BLOCK 0x92E2 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNKNOWN_CONTEXT_RESET 0x8255 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 -#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#define GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243 -#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 -#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 -#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A -#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 -#define GL_UNPACK_COMPRESSED_SIZE_SGIX 0x831A -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_UNPACK_FLIP_Y_WEBGL 0x9240 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_UNPACK_RESAMPLE_SGIX 0x842F -#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNSIGNALED 0x9118 -#define GL_UNSIGNALED_APPLE 0x9118 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_BYTE_2_3_3_REV_EXT 0x8362 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INT 0x1405 -#define GL_UNSIGNED_INT16_NV 0x8FF0 -#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 -#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 -#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_UNSIGNED_INT64_ARB 0x140F -#define GL_UNSIGNED_INT64_NV 0x140F -#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_UNSIGNED_INT8_NV 0x8FEC -#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED -#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE -#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_UNSIGNED_INT_24_8_MESA 0x8751 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#define GL_UNSIGNED_INT_24_8_OES 0x84FA -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_8_8_8_8_REV_EXT 0x8367 -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 -#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 -#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 -#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 -#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_EXT 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_5_6_5_REV_EXT 0x8364 -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_UPPER_LEFT 0x8CA2 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_UTF16_NV 0x909B -#define GL_UTF8_NV 0x909A -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_EXT 0x87C1 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VBO_FREE_MEMORY_ATI 0x87FB -#define GL_VECTOR_EXT 0x87BF -#define GL_VENDOR 0x1F00 -#define GL_VERSION 0x1F02 -#define GL_VERSION_ES_CL_1_0 1 -#define GL_VERSION_ES_CL_1_1 1 -#define GL_VERSION_ES_CM_1_1 1 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_VERTEX_ARRAY_KHR 0x8074 -#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A -#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E -#define GL_VERTEX_ATTRIB_BINDING 0x82D4 -#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 -#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 -#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 -#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 -#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 -#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 -#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 -#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 -#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 -#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 -#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 -#define GL_VERTEX_BINDING_BUFFER 0x8F4F -#define GL_VERTEX_BINDING_DIVISOR 0x82D6 -#define GL_VERTEX_BINDING_OFFSET 0x82D7 -#define GL_VERTEX_BINDING_STRIDE 0x82D8 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8BB7 -#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8BB6 -#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB5 -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8BB4 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SOURCE_ATI 0x8774 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SUBROUTINE 0x92E8 -#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE -#define GL_VERTEX_TEXTURE 0x829B -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_VERTICES_SUBMITTED_ARB 0x82EE -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 -#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D -#define GL_VIDEO_BUFFER_NV 0x9020 -#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 -#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B -#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A -#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 -#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 -#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C -#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 -#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 -#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A -#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B -#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C -#define GL_VIEWPORT 0x0BA2 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_VIEWPORT_BOUNDS_RANGE 0x825D -#define GL_VIEWPORT_BOUNDS_RANGE_EXT 0x825D -#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D -#define GL_VIEWPORT_COMMAND_NV 0x0010 -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_EXT 0x825F -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F -#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C -#define GL_VIEWPORT_SUBPIXEL_BITS_EXT 0x825C -#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C -#define GL_VIEW_CLASS_128_BITS 0x82C4 -#define GL_VIEW_CLASS_16_BITS 0x82CA -#define GL_VIEW_CLASS_24_BITS 0x82C9 -#define GL_VIEW_CLASS_32_BITS 0x82C8 -#define GL_VIEW_CLASS_48_BITS 0x82C7 -#define GL_VIEW_CLASS_64_BITS 0x82C6 -#define GL_VIEW_CLASS_8_BITS 0x82CB -#define GL_VIEW_CLASS_96_BITS 0x82C5 -#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 -#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 -#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 -#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 -#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC -#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD -#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE -#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF -#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 -#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 -#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 -#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 -#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 -#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 -#define GL_VIVIDLIGHT_NV 0x92A6 -#define GL_VOLATILE_APPLE 0x8A1A -#define GL_WAIT_FAILED 0x911D -#define GL_WAIT_FAILED_APPLE 0x911D -#define GL_WARPS_PER_SM_NV 0x933A -#define GL_WARP_SIZE_NV 0x9339 -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E -#define GL_WEIGHT_ARRAY_OES 0x86AD -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_WRAP_BORDER_SUN 0x81D4 -#define GL_WRITEONLY_RENDERING_QCOM 0x8823 -#define GL_WRITE_DISCARD_NV 0x88BE -#define GL_WRITE_ONLY 0x88B9 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_WRITE_ONLY_OES 0x88B9 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_W_EXT 0x87D8 -#define GL_XOR 0x1506 -#define GL_XOR_NV 0x1506 -#define GL_X_EXT 0x87D5 -#define GL_YCBAYCR8A_4224_NV 0x9032 -#define GL_YCBCR_422_APPLE 0x85B9 -#define GL_YCBCR_MESA 0x8757 -#define GL_YCBYCR8_422_NV 0x9031 -#define GL_YCRCBA_SGIX 0x8319 -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#define GL_YCRCB_SGIX 0x8318 -#define GL_Y_EXT 0x87D6 -#define GL_Z400_BINARY_AMD 0x8740 -#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 -#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 -#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 -#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 -#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 -#define GL_ZERO 0 -#define GL_ZERO_EXT 0x87DD -#define GL_ZERO_TO_ONE 0x935F -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_Z_EXT 0x87D7 +#define GL_1PASS_EXT 0x80A1 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2D 0x0600 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_2_BYTES 0x1407 +#define GL_2_BYTES_NV 0x1407 +#define GL_3D 0x0601 +#define GL_3DC_XY_AMD 0x87FA +#define GL_3DC_X_AMD 0x87F9 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_3_BYTES 0x1408 +#define GL_3_BYTES_NV 0x1408 +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_EXT 0x80CC +#define GL_422_REV_AVERAGE_EXT 0x80CF +#define GL_422_REV_EXT 0x80CD +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_4_BYTES 0x1409 +#define GL_4_BYTES_NV 0x1409 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_ABGR_EXT 0x8000 +#define GL_ACCUM 0x0100 +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_ADD 0x0104 +#define GL_ADD_ATI 0x8963 +#define GL_ADD_BLEND_IMG 0x8C09 +#define GL_ADD_SIGNED 0x8574 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_ALPHA 0x1906 +#define GL_ALPHA12 0x803D +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16 0x803E +#define GL_ALPHA16F_ARB 0x881C +#define GL_ALPHA16F_EXT 0x881C +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_ALPHA16_EXT 0x803E +#define GL_ALPHA16_SNORM 0x9018 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_ALPHA4 0x803B +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA8_OES 0x803C +#define GL_ALPHA8_SNORM 0x9014 +#define GL_ALPHA_BIAS 0x0D1D +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#define GL_ALPHA_MAX_SGIX 0x8321 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_REF_COMMAND_NV 0x000F +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_SNORM 0x9010 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_ALWAYS 0x0207 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_AMBIENT 0x1200 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ARC_TO_NV 0xFE +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_ASYNC_MARKER_SGIX 0x8329 +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ATTENUATION_EXT 0x834D +#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_AUX_BUFFERS 0x0C00 +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#define GL_AVERAGE_EXT 0x8335 +#define GL_AVERAGE_HP 0x8160 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_RIGHT 0x0403 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_BEVEL_NV 0x90A6 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_BGRA8_EXT 0x93A1 +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA_IMG 0x80E1 +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_BGR_EXT 0x80E0 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BITMAP 0x1A00 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_COLOR_COMMAND_NV 0x000B +#define GL_BLEND_COLOR_EXT 0x8005 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_DST_ALPHA_OES 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_DST_RGB_OES 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#define GL_BLEND_EQUATION_ALPHA_OES 0x883D +#define GL_BLEND_EQUATION_EXT 0x8009 +#define GL_BLEND_EQUATION_OES 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_RGB_OES 0x8009 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#define GL_BLEND_SRC_ALPHA_OES 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_SRC_RGB_OES 0x80C9 +#define GL_BLOCK_INDEX 0x92FD +#define GL_BLUE 0x1905 +#define GL_BLUE_BIAS 0x0D1B +#define GL_BLUE_BITS 0x0D54 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_BLUE_NV 0x1905 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BOLD_BIT_NV 0x01 +#define GL_BOOL 0x8B56 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_BROWSER_DEFAULT_WEBGL 0x9244 +#define GL_BUFFER 0x82E0 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_KHR 0x82E0 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_TARGET_ATI 0x877C +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_BYTE 0x1400 +#define GL_C3F_V3F 0x2A24 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_CCW 0x0901 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_CLAMP 0x2900 +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#define GL_CLAMP_TO_BORDER_EXT 0x812D +#define GL_CLAMP_TO_BORDER_NV 0x812D +#define GL_CLAMP_TO_BORDER_OES 0x812D +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLEAR 0x1500 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE0_APPLE 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE1_APPLE 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE2_APPLE 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE3_APPLE 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE4_APPLE 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE5_APPLE 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE6_APPLE 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_CLIP_DISTANCE7_APPLE 0x3007 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE0_IMG 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE1_IMG 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE2_IMG 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE3_IMG 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE4_IMG 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_CLIP_PLANE5_IMG 0x3005 +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_CMYKA_EXT 0x800D +#define GL_CMYK_EXT 0x800C +#define GL_CND0_ATI 0x896B +#define GL_CND_ATI 0x896A +#define GL_COEFF 0x0A00 +#define GL_COLOR 0x1800 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_COLORBURN 0x929A +#define GL_COLORBURN_KHR 0x929A +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE 0x9299 +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORDODGE_NV 0x9299 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_COLOR_ARRAY 0x8076 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT0_OES 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_COLOR_ENCODING 0x8296 +#define GL_COLOR_EXT 0x1800 +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#define GL_COLOR_INDEX 0x1900 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEXES 0x1603 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_COLOR_SUM 0x8458 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_COLOR_TABLE 0x80D0 +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMBINE 0x8570 +#define GL_COMBINE4_NV 0x8503 +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_COMBINE_ALPHA 0x8572 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPLETION_STATUS_ARB 0x91B1 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_R11_EAC_OES 0x9270 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RG11_EAC_OES 0x9272 +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_ETC2_OES 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276 +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278 +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 +#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 +#define GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 +#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 +#define GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 +#define GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 +#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 +#define GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 +#define GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 +#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 +#define GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_R11_EAC_OES 0x9271 +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SIGNED_RG11_EAC_OES 0x9273 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_ETC2_OES 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1 +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_CONFORMANT_NV 0x9374 +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_CONJOINT_NV 0x9284 +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B +#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 +#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_CONSTANT 0x8576 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_CONSTANT_ARB 0x8576 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_CONSTANT_EXT 0x8576 +#define GL_CONSTANT_NV 0x8576 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_CONTEXT_LOST 0x0507 +#define GL_CONTEXT_LOST_KHR 0x0507 +#define GL_CONTEXT_LOST_WEBGL 0x9242 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC +#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB +#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3 +#define GL_CONTINUOUS_AMD 0x9007 +#define GL_CONTRAST_NV 0x92A1 +#define GL_CONVEX_HULL_NV 0x908B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_2_ATI 0x8943 +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_COORD_REPLACE 0x8862 +#define GL_COORD_REPLACE_ARB 0x8862 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_COORD_REPLACE_OES 0x8862 +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_CUBIC_EXT 0x8334 +#define GL_CUBIC_HP 0x815F +#define GL_CUBIC_IMG 0x9139 +#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B +#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_CULL_MODES_NV 0x86E0 +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_IBM 103050 +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_CURRENT_BIT 0x00000001 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_CW 0x0900 +#define GL_DARKEN 0x9297 +#define GL_DARKEN_KHR 0x9297 +#define GL_DARKEN_NV 0x9297 +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_DEBUG_ASSERT_MESA 0x875B +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_OBJECT_MESA 0x8759 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_PRINT_MESA 0x875A +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DECAL 0x2101 +#define GL_DECODE_EXT 0x8A49 +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DECR_WRAP_EXT 0x8508 +#define GL_DECR_WRAP_OES 0x8508 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_DEPTH_ATTACHMENT_OES 0x8D00 +#define GL_DEPTH_BIAS 0x0D1F +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#define GL_DEPTH_CLAMP 0x864F +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_NV 0x864F +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_DEPTH_EXT 0x1801 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_DEPTH_STENCIL_MESA 0x8750 +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DIFFERENCE 0x929E +#define GL_DIFFERENCE_KHR 0x929E +#define GL_DIFFERENCE_NV 0x929E +#define GL_DIFFUSE 0x1201 +#define GL_DISCARD_ATI 0x8763 +#define GL_DISCARD_NV 0x8530 +#define GL_DISCRETE_AMD 0x9006 +#define GL_DISJOINT_NV 0x9283 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DISPLAY_LIST 0x82E7 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#define GL_DITHER 0x0BD0 +#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 +#define GL_DOMAIN 0x0A02 +#define GL_DONT_CARE 0x1100 +#define GL_DOT2_ADD_ATI 0x896C +#define GL_DOT3_ATI 0x8966 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_DOT3_RGBA_ARB 0x86AF +#define GL_DOT3_RGBA_EXT 0x8741 +#define GL_DOT3_RGBA_IMG 0x86AF +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT4_ATI 0x8967 +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DOUBLE_EXT 0x140A +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_VEC4_EXT 0x8FFE +#define GL_DOWNSAMPLE_SCALES_IMG 0x913E +#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 +#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 +#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 +#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 +#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_DSDT_NV 0x86F5 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_COLOR 0x0306 +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_BIAS_NV 0x8717 +#define GL_DT_SCALE_NV 0x8711 +#define GL_DU8DV8_ATI 0x877A +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_DUDV_ATI 0x8779 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_COPY_ARB 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_EDGE_FLAG 0x0B43 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_MAP_NV 0x855F +#define GL_EMISSION 0x1600 +#define GL_ENABLE_BIT 0x00002000 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_ETC1_RGB8_OES 0x8D64 +#define GL_ETC1_SRGB8_NV 0x88EE +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_BIT 0x00010000 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EXCLUSION 0x92A0 +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXTENSIONS 0x1F03 +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_EYE_PLANE 0x2502 +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_EYE_RADIAL_NV 0x855B +#define GL_E_TIMES_F_NV 0x8531 +#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07 +#define GL_FACTOR_MAX_AMD 0x901D +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FAILURE_NV 0x9030 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FEEDBACK 0x1C01 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_FENCE_APPLE 0x8A0B +#define GL_FENCE_CONDITION_NV 0x84F4 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 +#define GL_FIELDS_NV 0x8E27 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FILE_NAME_NV 0x9074 +#define GL_FILL 0x1B02 +#define GL_FILL_NV 0x1B02 +#define GL_FILL_RECTANGLE_NV 0x933C +#define GL_FILTER 0x829A +#define GL_FILTER4_SGIS 0x8146 +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D +#define GL_FIXED 0x140C +#define GL_FIXED_OES 0x140C +#define GL_FIXED_ONLY 0x891D +#define GL_FIXED_ONLY_ARB 0x891D +#define GL_FLAT 0x1D00 +#define GL_FLOAT 0x1406 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_MAT4x3_NV 0x8B6A +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_FOG 0x0B60 +#define GL_FOG_BIT 0x00000080 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_COORD 0x8451 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_FOG_END 0x0B64 +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_HINT 0x0C54 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#define GL_FOG_START 0x0B63 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_FRACTIONAL_EVEN_EXT 0x8E7C +#define GL_FRACTIONAL_EVEN_OES 0x8E7C +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_ODD_EXT 0x8E7B +#define GL_FRACTIONAL_ODD_OES 0x8E7B +#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314 +#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315 +#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313 +#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08 +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_FRAGMENT_INPUT_NV 0x936D +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3 +#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2 +#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1 +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 +#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6 +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC +#define GL_FRAMEBUFFER_OES 0x8D40 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAME_NV 0x8E26 +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_FACE_COMMAND_NV 0x0012 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_FUNC_ADD_OES 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_SUBTRACT_OES 0x800A +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F +#define GL_GEOMETRY_SHADER_OES 0x8DD9 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEQUAL 0x0206 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_GREEN_BIAS 0x0D19 +#define GL_GREEN_BITS 0x0D53 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_GREEN_NV 0x1904 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GS_PROGRAM_BINARY_MTK 0x9641 +#define GL_GS_SHADER_BINARY_MTK 0x9640 +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253 +#define GL_HALF_APPLE 0x140B +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_HALF_FLOAT 0x140B +#define GL_HALF_FLOAT_ARB 0x140B +#define GL_HALF_FLOAT_NV 0x140B +#define GL_HALF_FLOAT_OES 0x8D61 +#define GL_HARDLIGHT 0x929B +#define GL_HARDLIGHT_KHR 0x929B +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_HILO16_NV 0x86F8 +#define GL_HILO8_NV 0x885E +#define GL_HILO_NV 0x86F4 +#define GL_HINT_BIT 0x00008000 +#define GL_HISTOGRAM 0x8024 +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_SINK 0x802D +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HI_BIAS_NV 0x8714 +#define GL_HI_SCALE_NV 0x870E +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_HSL_COLOR 0x92AF +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE 0x92AD +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY 0x92B0 +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION 0x92AE +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_IDENTITY_NV 0x862A +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_BUFFER_OES 0x9051 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_INCR_WRAP_OES 0x8507 +#define GL_INDEX 0x8222 +#define GL_INDEX_ARRAY 0x8077 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_BITS 0x0D51 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254 +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#define GL_INT 0x1404 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_ARB 0x140E +#define GL_INT64_NV 0x140E +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16 0x804D +#define GL_INTENSITY16F_ARB 0x881D +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_INTENSITY16_EXT 0x804D +#define GL_INTENSITY16_SNORM 0x901B +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_INGR 0x8568 +#define GL_INTERLACE_READ_OML 0x8981 +#define GL_INTERLACE_SGIX 0x8094 +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERPOLATE 0x8575 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_BUFFER_OES 0x905C +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_INVARIANT_EXT 0x87C2 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVERSE_NV 0x862B +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_INVERT 0x150A +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#define GL_ISOLINES 0x8E7A +#define GL_ISOLINES_EXT 0x8E7A +#define GL_ISOLINES_OES 0x8E7A +#define GL_IS_PER_PATCH 0x92E7 +#define GL_IS_PER_PATCH_EXT 0x92E7 +#define GL_IS_PER_PATCH_OES 0x92E7 +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_KEEP 0x1E00 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_LAYER_NV 0x8DAA +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LERP_ATI 0x8969 +#define GL_LESS 0x0201 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_LIGHTEN 0x9298 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINES 0x0001 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINES_ADJACENCY_OES 0x000A +#define GL_LINE_BIT 0x00000004 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_NV 0x1B01 +#define GL_LINE_QUALITY_HINT_SGIX 0x835B +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_LINE_STRIP_ADJACENCY_OES 0x000B +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_TO_NV 0x04 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_COMMAND_NV 0x000D +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINK_STATUS 0x8B82 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_BIT 0x00020000 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 +#define GL_LIST_PRIORITY_SGIX 0x8182 +#define GL_LOAD 0x0101 +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_EXT 0x87C4 +#define GL_LOCATION 0x930E +#define GL_LOCATION_COMPONENT 0x934A +#define GL_LOCATION_INDEX 0x930F +#define GL_LOCATION_INDEX_EXT 0x930F +#define GL_LOGIC_OP 0x0BF1 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_LO_BIAS_NV 0x8715 +#define GL_LO_SCALE_NV 0x870F +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_MAD_ATI 0x8968 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_MAJOR_VERSION 0x821B +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_STENCIL 0x0D11 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX7_NV 0x8637 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX_EXT 0x87C0 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E +#define GL_MATRIX_INDEX_ARRAY_OES 0x8844 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MATRIX_PALETTE_OES 0x8840 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_CLIP_PLANES_IMG 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_EXT 0x8008 +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 +#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_MAX_PALETTE_MATRICES_OES 0x8842 +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D +#define GL_MAX_PATCH_VERTICES_OES 0x8E7D +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 +#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_MAX_SAMPLES_NV 0x8D57 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 +#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E +#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 +#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_MAX_VERTEX_UNITS_OES 0x86A4 +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VIEWPORTS 0x825B +#define GL_MAX_VIEWPORTS_NV 0x825B +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_MAX_WIDTH 0x827E +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_MIN 0x8007 +#define GL_MINMAX 0x802E +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_MINOR_VERSION 0x821C +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MIN_EXT 0x8007 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIPMAP 0x8293 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#define GL_MIRRORED_REPEAT_OES 0x8370 +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_MODELVIEW 0x1700 +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW1_EXT 0x850A +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_MODULATE 0x2100 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_COLOR_IMG 0x8C04 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_MOVE_TO_NV 0x02 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOV_ATI 0x8961 +#define GL_MULT 0x0103 +#define GL_MULTIPLY 0x9294 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_MULTIPLY_NV 0x9294 +#define GL_MULTISAMPLE 0x809D +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_MUL_ATI 0x8964 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_N3F_V3F 0x2A25 +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +#define GL_NAME_LENGTH 0x92F9 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_NAND 0x150E +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NEAREST 0x2600 +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEVER 0x0200 +#define GL_NEXT_BUFFER_NV -2 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NONE_OES 0 +#define GL_NOOP 0x1505 +#define GL_NOP_COMMAND_NV 0x0001 +#define GL_NOR 0x1508 +#define GL_NORMALIZE 0x0BA1 +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_NORMAL_MAP_OES 0x8511 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#define GL_NO_RESET_NOTIFICATION_KHR 0x8261 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D +#define GL_NUM_EXTENSIONS 0x821D +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA +#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_PLANE 0x2501 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_OBJECT_TYPE 0x9112 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#define GL_OFFSET 0x92FC +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_ONE 1 +#define GL_ONE_EXT 0x87DE +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND3_ALPHA_NV 0x859B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_MOV_EXT 0x8799 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_SUB_EXT 0x8796 +#define GL_OR 0x1507 +#define GL_ORDER 0x0A01 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_OVERLAY 0x9296 +#define GL_OVERLAY_KHR 0x9296 +#define GL_OVERLAY_NV 0x9296 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_SIZE_SGIX 0x831C +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_PACK_INVERT_MESA 0x8758 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_PATCHES 0x000E +#define GL_PATCHES_EXT 0x000E +#define GL_PATCHES_OES 0x000E +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_INNER_LEVEL_EXT 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_PATCH_DEFAULT_OUTER_LEVEL_EXT 0x8E74 +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_VERTICES_EXT 0x8E72 +#define GL_PATCH_VERTICES_OES 0x8E72 +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_PERTURB_EXT 0x85AE +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#define GL_PHONG_HINT_WIN 0x80EB +#define GL_PHONG_WIN 0x80EA +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_BIT 0x00000002 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_POINT_NV 0x1B00 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F +#define GL_POINT_SIZE_ARRAY_OES 0x8B9C +#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C +#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B +#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_POINT_SPRITE 0x8861 +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_POINT_SPRITE_OES 0x8861 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#define GL_POINT_TOKEN 0x0701 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_MODE_NV 0x0B40 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_POSITION 0x1203 +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_PRESENT_DURATION_NV 0x8E2B +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESERVE_ATI 0x8762 +#define GL_PREVIOUS 0x8578 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_PRIMITIVES_GENERATED_OES 0x8C87 +#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF +#define GL_PRIMITIVE_BOUNDING_BOX 0x92BE +#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE +#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE +#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PROGRAM 0x82E2 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#define GL_PROGRAM_PIPELINE_KHR 0x82E4 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROJECTION 0x1701 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_PURGEABLE_APPLE 0x8A1D +#define GL_Q 0x2003 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_QUADS 0x0007 +#define GL_QUADS_EXT 0x0007 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_QUADS_OES 0x0007 +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_QUAD_STRIP 0x0008 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_QUERY 0x82E3 +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_KHR 0x82E3 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_TARGET 0x82EA +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_R 0x2002 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R11F_G11F_B10F_APPLE 0x8C3A +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16F_EXT 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R16_EXT 0x822A +#define GL_R16_SNORM 0x8F98 +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R32F 0x822E +#define GL_R32F_EXT 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R3_G3_B2 0x2A10 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_EXT 0x8229 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_READ_BUFFER_NV 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_READ_ONLY 0x88B8 +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#define GL_READ_WRITE 0x88BA +#define GL_READ_WRITE_ARB 0x88BA +#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05 +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_RECT_NV 0xF6 +#define GL_RED 0x1903 +#define GL_REDUCE 0x8016 +#define GL_REDUCE_EXT 0x8016 +#define GL_RED_BIAS 0x0D15 +#define GL_RED_BITS 0x0D52 +#define GL_RED_BIT_ATI 0x00000001 +#define GL_RED_EXT 0x1903 +#define GL_RED_INTEGER 0x8D94 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_RED_NV 0x1903 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_SNORM 0x8F90 +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFLECTION_MAP 0x8512 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_REFLECTION_MAP_NV 0x8512 +#define GL_REFLECTION_MAP_OES 0x8512 +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_2_ATI 0x8923 +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_RENDER 0x1C00 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BINDING_ANGLE 0x8CA7 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_RENDERBUFFER_BINDING_OES 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52 +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44 +#define GL_RENDERBUFFER_OES 0x8D41 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_WIDTH_OES 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#define GL_RENDER_MODE 0x0C40 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACE_EXT 0x8062 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_REPLICATE_BORDER 0x8153 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 +#define GL_RESCALE_NORMAL 0x803A +#define GL_RESCALE_NORMAL_EXT 0x803A +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_RESTART_SUN 0x0001 +#define GL_RETAINED_APPLE 0x8A1B +#define GL_RETURN 0x0102 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16F_EXT 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG16_EXT 0x822C +#define GL_RG16_SNORM 0x8F99 +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RG32F 0x8230 +#define GL_RG32F_EXT 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_EXT 0x822B +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB16F 0x881B +#define GL_RGB16F_ARB 0x881B +#define GL_RGB16F_EXT 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16I_EXT 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_RGB16_EXT 0x8054 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB16_SNORM_EXT 0x8F9A +#define GL_RGB2_EXT 0x804E +#define GL_RGB32F 0x8815 +#define GL_RGB32F_ARB 0x8815 +#define GL_RGB32F_EXT 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32I_EXT 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_RGB4 0x804F +#define GL_RGB4_EXT 0x804F +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGB5 0x8050 +#define GL_RGB565 0x8D62 +#define GL_RGB565_OES 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8I_EXT 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8UI_EXT 0x8D7D +#define GL_RGB8_EXT 0x8051 +#define GL_RGB8_OES 0x8051 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGB9_E5_APPLE 0x8C3D +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA16F 0x881A +#define GL_RGBA16F_ARB 0x881A +#define GL_RGBA16F_EXT 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGBA16_EXT 0x805B +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA16_SNORM_EXT 0x8F9B +#define GL_RGBA2 0x8055 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA4_DXT5_S3TC 0x83A5 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGBA4_OES 0x8056 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGBA8_EXT 0x8058 +#define GL_RGBA8_OES 0x8058 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#define GL_RGBA_MODE 0x0C31 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#define GL_RGBA_SNORM 0x8F93 +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGB_RAW_422_APPLE 0x8A51 +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB_SCALE 0x8573 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_RGB_SNORM 0x8F92 +#define GL_RG_EXT 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_RG_SNORM 0x8F91 +#define GL_RIGHT 0x0407 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_ROUND_NV 0x90A4 +#define GL_S 0x2000 +#define GL_SAMPLER 0x82E6 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_BUFFER_OES 0x8DC2 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_SAMPLER_KHR 0x82E6 +#define GL_SAMPLER_OBJECT_AMD 0x9155 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_LOCATION_ARB 0x8E50 +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_SAMPLE_SHADING_OES 0x8C36 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_SCALAR_EXT 0x87BE +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCISSOR_BIT 0x00080000 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_COMMAND_NV 0x0011 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SCREEN 0x9295 +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_SCREEN_KHR 0x9295 +#define GL_SCREEN_NV 0x9295 +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_SELECT 0x1C02 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_SEPARABLE_2D 0x8012 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#define GL_SET 0x150F +#define GL_SET_AMD 0x874A +#define GL_SGX_BINARY_IMG 0x8C0A +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#define GL_SHADER 0x82E1 +#define GL_SHADER_BINARY_DMP 0x9250 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_BINARY_VIV 0x8FC4 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_SHADER_KHR 0x82E1 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADE_MODEL 0x0B54 +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_SHARED_EDGE_NV 0xC0 +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#define GL_SHININESS 0x1601 +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SKIP_COMPONENTS1_NV -6 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS4_NV -3 +#define GL_SKIP_DECODE_EXT 0x8A4A +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_SLICE_ACCUM_SUN 0x85CC +#define GL_SLIM10U_SGIX 0x831E +#define GL_SLIM12S_SGIX 0x831F +#define GL_SLIM8U_SGIX 0x831D +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 +#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 +#define GL_SMOOTH 0x1D01 +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_SM_COUNT_NV 0x933B +#define GL_SOFTLIGHT 0x929C +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SPARE0_NV 0x852E +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_SPARE1_NV 0x852F +#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 +#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 +#define GL_SPECULAR 0x1202 +#define GL_SPHERE_MAP 0x2402 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SQUARE_NV 0x90A3 +#define GL_SR8_EXT 0x8FBD +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_ALPHA 0x8589 +#define GL_SRC1_ALPHA_EXT 0x8589 +#define GL_SRC1_COLOR 0x88F9 +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_ALPHA 0x858A +#define GL_SRC2_RGB 0x8582 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_COLOR 0x0300 +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_SRG8_EXT 0x8FBE +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB8_NV 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB_DECODE_ARB 0x8299 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_STATE_RESTORE 0x8BDC +#define GL_STATIC_ATI 0x8760 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_STENCIL_ATTACHMENT_OES 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_STENCIL_EXT 0x1802 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX8_OES 0x8D48 +#define GL_STENCIL_INDEX_OES 0x1901 +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_REF_COMMAND_NV 0x000C +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_SHARED_APPLE 0x85BF +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#define GL_SUBTRACT 0x84E7 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_SUB_ATI 0x8965 +#define GL_SUCCESS_NV 0x902F +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_T 0x2001 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_T4F_V4F 0x2A28 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 +#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 +#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 +#define GL_TESS_CONTROL_SHADER_OES 0x8E88 +#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 +#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 +#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 +#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_MODE_EXT 0x8E76 +#define GL_TESS_GEN_MODE_OES 0x8E76 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 +#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_SPACING_EXT 0x8E77 +#define GL_TESS_GEN_SPACING_OES 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 +#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE31_ARB 0x84DF +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#define GL_TEXTURE_3D_BINDING_OES 0x806A +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06 +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#define GL_TEXTURE_BUFFER_OES 0x8C2A +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F +#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E +#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_CROP_RECT_OES 0x8B9D +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 +#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A +#define GL_TEXTURE_CUBE_MAP_OES 0x8513 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_GEN_MODE_OES 0x2500 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_STR_OES 0x8D60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_TEXTURE_SPARSE_EXT 0x91A6 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_TARGET 0x1006 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD +#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB +#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE +#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC +#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFF +#define GL_TIMESTAMP 0x8E28 +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRACE_ALL_BITS_MESA 0xFFFF +#define GL_TRACE_ARRAYS_BIT_MESA 0x0004 +#define GL_TRACE_ERRORS_BIT_MESA 0x0020 +#define GL_TRACE_MASK_MESA 0x8755 +#define GL_TRACE_NAME_MESA 0x8756 +#define GL_TRACE_OPERATIONS_BIT_MESA 0x0001 +#define GL_TRACE_PIXELS_BIT_MESA 0x0010 +#define GL_TRACE_PRIMITIVES_BIT_MESA 0x0002 +#define GL_TRACE_TEXTURES_BIT_MESA 0x0008 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_NV 0x862C +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLES_ADJACENCY_OES 0x000C +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_TRUE 1 +#define GL_TYPE 0x92FA +#define GL_UNCORRELATED_NV 0x9282 +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_UNDEFINED_VERTEX_OES 0x8260 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#define GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_SIZE_SGIX 0x831A +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_UNPACK_FLIP_Y_WEBGL 0x9240 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_2_3_3_REV_EXT 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_UNSIGNED_INT64_ARB 0x140F +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_UNSIGNED_INT_24_8_MESA 0x8751 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_8_8_8_8_REV_EXT 0x8367 +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 +#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_EXT 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_5_6_5_REV_EXT 0x8364 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_UPPER_LEFT 0x8CA2 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_UTF16_NV 0x909B +#define GL_UTF8_NV 0x909A +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_EXT 0x87C1 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_VECTOR_EXT 0x87BF +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERSION_ES_CL_1_0 1 +#define GL_VERSION_ES_CL_1_1 1 +#define GL_VERSION_ES_CM_1_1 1 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8BB7 +#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8BB6 +#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB5 +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8BB4 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_VERTEX_TEXTURE 0x829B +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_VERTICES_SUBMITTED_ARB 0x82EE +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIEWPORT 0x0BA2 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_BOUNDS_RANGE_EXT 0x825D +#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D +#define GL_VIEWPORT_COMMAND_NV 0x0010 +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_EXT 0x825F +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_SUBPIXEL_BITS_EXT 0x825C +#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_WAIT_FAILED 0x911D +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WEIGHTED_AVERAGE_ARB 0x9367 +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E +#define GL_WEIGHT_ARRAY_OES 0x86AD +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_WRAP_BORDER_SUN 0x81D4 +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#define GL_WRITE_DISCARD_NV 0x88BE +#define GL_WRITE_ONLY 0x88B9 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_W_EXT 0x87D8 +#define GL_XOR 0x1506 +#define GL_XOR_NV 0x1506 +#define GL_X_EXT 0x87D5 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_YCBCR_MESA 0x8757 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCRCBA_SGIX 0x8319 +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#define GL_YCRCB_SGIX 0x8318 +#define GL_Y_EXT 0x87D6 +#define GL_Z400_BINARY_AMD 0x8740 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_ZERO 0 +#define GL_ZERO_EXT 0x87DD +#define GL_ZERO_TO_ONE 0x935F +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_Z_EXT 0x87D7 +#define WGL_RENDERER_ACCELERATED_WINE 0x8186 +#define WGL_RENDERER_DEVICE_ID_WINE 0x8184 +#define WGL_RENDERER_ID_WINE 0x818E +#define WGL_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_WINE 0x818B +#define WGL_RENDERER_OPENGL_CORE_PROFILE_VERSION_WINE 0x818A +#define WGL_RENDERER_OPENGL_ES2_PROFILE_VERSION_WINE 0x818D +#define WGL_RENDERER_OPENGL_ES_PROFILE_VERSION_WINE 0x818C +#define WGL_RENDERER_PREFERRED_PROFILE_WINE 0x8189 +#define WGL_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_WINE 0x8188 +#define WGL_RENDERER_VENDOR_ID_WINE 0x8183 +#define WGL_RENDERER_VERSION_WINE 0x8185 +#define WGL_RENDERER_VIDEO_MEMORY_WINE 0x8187 void GLAPIENTRY glAccum(GLenum,GLfloat); void GLAPIENTRY glAlphaFunc(GLenum,GLfloat); diff --git a/reactos/sdk/include/reactos/wine/wgl_driver.h b/reactos/sdk/include/reactos/wine/wgl_driver.h index 046b6040691..283cf4a170c 100644 --- a/reactos/sdk/include/reactos/wine/wgl_driver.h +++ b/reactos/sdk/include/reactos/wine/wgl_driver.h @@ -7,7 +7,7 @@ #define WINE_GLAPI #endif -#define WINE_WGL_DRIVER_VERSION 13 +#define WINE_WGL_DRIVER_VERSION 15 struct wgl_context; struct wgl_pbuffer; @@ -381,6 +381,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glAlphaFragmentOp2ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glAlphaFragmentOp3ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glAlphaFuncxOES)(GLenum,GLfixed); + void (WINE_GLAPI *p_glApplyFramebufferAttachmentCMAAINTEL)(void); void (WINE_GLAPI *p_glApplyTextureEXT)(GLenum); GLboolean (WINE_GLAPI *p_glAreProgramsResidentNV)(GLsizei,const GLuint*,GLboolean*); GLboolean (WINE_GLAPI *p_glAreTexturesResidentEXT)(GLsizei,const GLuint*,GLboolean*); @@ -526,7 +527,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glClearNamedBufferDataEXT)(GLuint,GLenum,GLenum,GLenum,const void*); void (WINE_GLAPI *p_glClearNamedBufferSubData)(GLuint,GLenum,GLintptr,GLsizeiptr,GLenum,GLenum,const void*); void (WINE_GLAPI *p_glClearNamedBufferSubDataEXT)(GLuint,GLenum,GLsizeiptr,GLsizeiptr,GLenum,GLenum,const void*); - void (WINE_GLAPI *p_glClearNamedFramebufferfi)(GLuint,GLenum,const GLfloat,GLint); + void (WINE_GLAPI *p_glClearNamedFramebufferfi)(GLuint,GLenum,GLint,GLfloat,GLint); void (WINE_GLAPI *p_glClearNamedFramebufferfv)(GLuint,GLenum,GLint,const GLfloat*); void (WINE_GLAPI *p_glClearNamedFramebufferiv)(GLuint,GLenum,GLint,const GLint*); void (WINE_GLAPI *p_glClearNamedFramebufferuiv)(GLuint,GLenum,GLint,const GLuint*); @@ -617,6 +618,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glCompressedTextureSubImage2DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLsizei,const void*); void (WINE_GLAPI *p_glCompressedTextureSubImage3D)(GLuint,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const void*); void (WINE_GLAPI *p_glCompressedTextureSubImage3DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const void*); + void (WINE_GLAPI *p_glConservativeRasterParameterfNV)(GLenum,GLfloat); void (WINE_GLAPI *p_glConvolutionFilter1D)(GLenum,GLenum,GLsizei,GLenum,GLenum,const void*); void (WINE_GLAPI *p_glConvolutionFilter1DEXT)(GLenum,GLenum,GLsizei,GLenum,GLenum,const void*); void (WINE_GLAPI *p_glConvolutionFilter2D)(GLenum,GLenum,GLsizei,GLsizei,GLenum,GLenum,const void*); @@ -836,6 +838,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glEvalCoord2xOES)(GLfixed,GLfixed); void (WINE_GLAPI *p_glEvalCoord2xvOES)(const GLfixed*); void (WINE_GLAPI *p_glEvalMapsNV)(GLenum,GLenum); + void (WINE_GLAPI *p_glEvaluateDepthValuesARB)(void); void (WINE_GLAPI *p_glExecuteProgramNV)(GLenum,GLuint,const GLfloat*); void (WINE_GLAPI *p_glExtractComponentEXT)(GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glFeedbackBufferxOES)(GLsizei,GLenum,const GLfixed*); @@ -894,6 +897,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glFramebufferReadBufferEXT)(GLuint,GLenum); void (WINE_GLAPI *p_glFramebufferRenderbuffer)(GLenum,GLenum,GLenum,GLuint); void (WINE_GLAPI *p_glFramebufferRenderbufferEXT)(GLenum,GLenum,GLenum,GLuint); + void (WINE_GLAPI *p_glFramebufferSampleLocationsfvARB)(GLenum,GLuint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glFramebufferSampleLocationsfvNV)(GLenum,GLuint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glFramebufferTexture)(GLenum,GLenum,GLuint,GLint); void (WINE_GLAPI *p_glFramebufferTexture1D)(GLenum,GLenum,GLenum,GLuint,GLint); @@ -909,6 +913,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glFramebufferTextureLayer)(GLenum,GLenum,GLuint,GLint,GLint); void (WINE_GLAPI *p_glFramebufferTextureLayerARB)(GLenum,GLenum,GLuint,GLint,GLint); void (WINE_GLAPI *p_glFramebufferTextureLayerEXT)(GLenum,GLenum,GLuint,GLint,GLint); + void (WINE_GLAPI *p_glFramebufferTextureMultiviewOVR)(GLenum,GLenum,GLuint,GLint,GLint,GLsizei); void (WINE_GLAPI *p_glFreeObjectBufferATI)(GLuint); void (WINE_GLAPI *p_glFrustumfOES)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat); void (WINE_GLAPI *p_glFrustumxOES)(GLfixed,GLfixed,GLfixed,GLfixed,GLfixed,GLfixed); @@ -1268,9 +1273,11 @@ struct opengl_funcs void (WINE_GLAPI *p_glGetUniformdv)(GLuint,GLint,GLdouble*); void (WINE_GLAPI *p_glGetUniformfv)(GLuint,GLint,GLfloat*); void (WINE_GLAPI *p_glGetUniformfvARB)(GLhandleARB,GLint,GLfloat*); + void (WINE_GLAPI *p_glGetUniformi64vARB)(GLuint,GLint,GLint64*); void (WINE_GLAPI *p_glGetUniformi64vNV)(GLuint,GLint,GLint64EXT*); void (WINE_GLAPI *p_glGetUniformiv)(GLuint,GLint,GLint*); void (WINE_GLAPI *p_glGetUniformivARB)(GLhandleARB,GLint,GLint*); + void (WINE_GLAPI *p_glGetUniformui64vARB)(GLuint,GLint,GLuint64*); void (WINE_GLAPI *p_glGetUniformui64vNV)(GLuint,GLint,GLuint64EXT*); void (WINE_GLAPI *p_glGetUniformuiv)(GLuint,GLint,GLuint*); void (WINE_GLAPI *p_glGetUniformuivEXT)(GLuint,GLint,GLuint*); @@ -1351,8 +1358,10 @@ struct opengl_funcs void (WINE_GLAPI *p_glGetnUniformdvARB)(GLuint,GLint,GLsizei,GLdouble*); void (WINE_GLAPI *p_glGetnUniformfv)(GLuint,GLint,GLsizei,GLfloat*); void (WINE_GLAPI *p_glGetnUniformfvARB)(GLuint,GLint,GLsizei,GLfloat*); + void (WINE_GLAPI *p_glGetnUniformi64vARB)(GLuint,GLint,GLsizei,GLint64*); void (WINE_GLAPI *p_glGetnUniformiv)(GLuint,GLint,GLsizei,GLint*); void (WINE_GLAPI *p_glGetnUniformivARB)(GLuint,GLint,GLsizei,GLint*); + void (WINE_GLAPI *p_glGetnUniformui64vARB)(GLuint,GLint,GLsizei,GLuint64*); void (WINE_GLAPI *p_glGetnUniformuiv)(GLuint,GLint,GLsizei,GLuint*); void (WINE_GLAPI *p_glGetnUniformuivARB)(GLuint,GLint,GLsizei,GLuint*); void (WINE_GLAPI *p_glGlobalAlphaFactorbSUN)(GLbyte); @@ -1521,6 +1530,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glMatrixScalefEXT)(GLenum,GLfloat,GLfloat,GLfloat); void (WINE_GLAPI *p_glMatrixTranslatedEXT)(GLenum,GLdouble,GLdouble,GLdouble); void (WINE_GLAPI *p_glMatrixTranslatefEXT)(GLenum,GLfloat,GLfloat,GLfloat); + void (WINE_GLAPI *p_glMaxShaderCompilerThreadsARB)(GLuint); void (WINE_GLAPI *p_glMemoryBarrier)(GLbitfield); void (WINE_GLAPI *p_glMemoryBarrierByRegion)(GLbitfield); void (WINE_GLAPI *p_glMemoryBarrierEXT)(GLbitfield); @@ -1723,6 +1733,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glNamedFramebufferReadBuffer)(GLuint,GLenum); void (WINE_GLAPI *p_glNamedFramebufferRenderbuffer)(GLuint,GLenum,GLenum,GLuint); void (WINE_GLAPI *p_glNamedFramebufferRenderbufferEXT)(GLuint,GLenum,GLenum,GLuint); + void (WINE_GLAPI *p_glNamedFramebufferSampleLocationsfvARB)(GLuint,GLuint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glNamedFramebufferSampleLocationsfvNV)(GLuint,GLuint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glNamedFramebufferTexture)(GLuint,GLenum,GLuint,GLint); void (WINE_GLAPI *p_glNamedFramebufferTexture1DEXT)(GLuint,GLenum,GLenum,GLuint,GLint); @@ -1847,6 +1858,7 @@ struct opengl_funcs void (WINE_GLAPI *p_glPopGroupMarkerEXT)(void); void (WINE_GLAPI *p_glPresentFrameDualFillNV)(GLuint,GLuint64EXT,GLuint,GLuint,GLenum,GLenum,GLuint,GLenum,GLuint,GLenum,GLuint,GLenum,GLuint); void (WINE_GLAPI *p_glPresentFrameKeyedNV)(GLuint,GLuint64EXT,GLuint,GLuint,GLenum,GLenum,GLuint,GLuint,GLenum,GLuint,GLuint); + void (WINE_GLAPI *p_glPrimitiveBoundingBoxARB)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat); void (WINE_GLAPI *p_glPrimitiveRestartIndex)(GLuint); void (WINE_GLAPI *p_glPrimitiveRestartIndexNV)(GLuint); void (WINE_GLAPI *p_glPrimitiveRestartNV)(void); @@ -1903,13 +1915,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glProgramUniform1fv)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform1fvEXT)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform1i)(GLuint,GLint,GLint); + void (WINE_GLAPI *p_glProgramUniform1i64ARB)(GLuint,GLint,GLint64); void (WINE_GLAPI *p_glProgramUniform1i64NV)(GLuint,GLint,GLint64EXT); + void (WINE_GLAPI *p_glProgramUniform1i64vARB)(GLuint,GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glProgramUniform1i64vNV)(GLuint,GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glProgramUniform1iEXT)(GLuint,GLint,GLint); void (WINE_GLAPI *p_glProgramUniform1iv)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform1ivEXT)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform1ui)(GLuint,GLint,GLuint); + void (WINE_GLAPI *p_glProgramUniform1ui64ARB)(GLuint,GLint,GLuint64); void (WINE_GLAPI *p_glProgramUniform1ui64NV)(GLuint,GLint,GLuint64EXT); + void (WINE_GLAPI *p_glProgramUniform1ui64vARB)(GLuint,GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glProgramUniform1ui64vNV)(GLuint,GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glProgramUniform1uiEXT)(GLuint,GLint,GLuint); void (WINE_GLAPI *p_glProgramUniform1uiv)(GLuint,GLint,GLsizei,const GLuint*); @@ -1923,13 +1939,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glProgramUniform2fv)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform2fvEXT)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform2i)(GLuint,GLint,GLint,GLint); + void (WINE_GLAPI *p_glProgramUniform2i64ARB)(GLuint,GLint,GLint64,GLint64); void (WINE_GLAPI *p_glProgramUniform2i64NV)(GLuint,GLint,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glProgramUniform2i64vARB)(GLuint,GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glProgramUniform2i64vNV)(GLuint,GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glProgramUniform2iEXT)(GLuint,GLint,GLint,GLint); void (WINE_GLAPI *p_glProgramUniform2iv)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform2ivEXT)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform2ui)(GLuint,GLint,GLuint,GLuint); + void (WINE_GLAPI *p_glProgramUniform2ui64ARB)(GLuint,GLint,GLuint64,GLuint64); void (WINE_GLAPI *p_glProgramUniform2ui64NV)(GLuint,GLint,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glProgramUniform2ui64vARB)(GLuint,GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glProgramUniform2ui64vNV)(GLuint,GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glProgramUniform2uiEXT)(GLuint,GLint,GLuint,GLuint); void (WINE_GLAPI *p_glProgramUniform2uiv)(GLuint,GLint,GLsizei,const GLuint*); @@ -1943,13 +1963,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glProgramUniform3fv)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform3fvEXT)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform3i)(GLuint,GLint,GLint,GLint,GLint); + void (WINE_GLAPI *p_glProgramUniform3i64ARB)(GLuint,GLint,GLint64,GLint64,GLint64); void (WINE_GLAPI *p_glProgramUniform3i64NV)(GLuint,GLint,GLint64EXT,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glProgramUniform3i64vARB)(GLuint,GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glProgramUniform3i64vNV)(GLuint,GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glProgramUniform3iEXT)(GLuint,GLint,GLint,GLint,GLint); void (WINE_GLAPI *p_glProgramUniform3iv)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform3ivEXT)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform3ui)(GLuint,GLint,GLuint,GLuint,GLuint); + void (WINE_GLAPI *p_glProgramUniform3ui64ARB)(GLuint,GLint,GLuint64,GLuint64,GLuint64); void (WINE_GLAPI *p_glProgramUniform3ui64NV)(GLuint,GLint,GLuint64EXT,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glProgramUniform3ui64vARB)(GLuint,GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glProgramUniform3ui64vNV)(GLuint,GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glProgramUniform3uiEXT)(GLuint,GLint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glProgramUniform3uiv)(GLuint,GLint,GLsizei,const GLuint*); @@ -1963,13 +1987,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glProgramUniform4fv)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform4fvEXT)(GLuint,GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glProgramUniform4i)(GLuint,GLint,GLint,GLint,GLint,GLint); + void (WINE_GLAPI *p_glProgramUniform4i64ARB)(GLuint,GLint,GLint64,GLint64,GLint64,GLint64); void (WINE_GLAPI *p_glProgramUniform4i64NV)(GLuint,GLint,GLint64EXT,GLint64EXT,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glProgramUniform4i64vARB)(GLuint,GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glProgramUniform4i64vNV)(GLuint,GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glProgramUniform4iEXT)(GLuint,GLint,GLint,GLint,GLint,GLint); void (WINE_GLAPI *p_glProgramUniform4iv)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform4ivEXT)(GLuint,GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glProgramUniform4ui)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint); + void (WINE_GLAPI *p_glProgramUniform4ui64ARB)(GLuint,GLint,GLuint64,GLuint64,GLuint64,GLuint64); void (WINE_GLAPI *p_glProgramUniform4ui64NV)(GLuint,GLint,GLuint64EXT,GLuint64EXT,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glProgramUniform4ui64vARB)(GLuint,GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glProgramUniform4ui64vNV)(GLuint,GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glProgramUniform4uiEXT)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glProgramUniform4uiv)(GLuint,GLint,GLsizei,const GLuint*); @@ -2080,7 +2108,6 @@ struct opengl_funcs void (WINE_GLAPI *p_glRotatexOES)(GLfixed,GLfixed,GLfixed,GLfixed); void (WINE_GLAPI *p_glSampleCoverage)(GLfloat,GLboolean); void (WINE_GLAPI *p_glSampleCoverageARB)(GLfloat,GLboolean); - void (WINE_GLAPI *p_glSampleCoverageOES)(GLfixed,GLboolean); void (WINE_GLAPI *p_glSampleMapATI)(GLuint,GLuint,GLenum); void (WINE_GLAPI *p_glSampleMaskEXT)(GLclampf,GLboolean); void (WINE_GLAPI *p_glSampleMaskIndexedNV)(GLuint,GLbitfield); @@ -2355,13 +2382,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glUniform1fv)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform1fvARB)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform1i)(GLint,GLint); + void (WINE_GLAPI *p_glUniform1i64ARB)(GLint,GLint64); void (WINE_GLAPI *p_glUniform1i64NV)(GLint,GLint64EXT); + void (WINE_GLAPI *p_glUniform1i64vARB)(GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glUniform1i64vNV)(GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glUniform1iARB)(GLint,GLint); void (WINE_GLAPI *p_glUniform1iv)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform1ivARB)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform1ui)(GLint,GLuint); + void (WINE_GLAPI *p_glUniform1ui64ARB)(GLint,GLuint64); void (WINE_GLAPI *p_glUniform1ui64NV)(GLint,GLuint64EXT); + void (WINE_GLAPI *p_glUniform1ui64vARB)(GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glUniform1ui64vNV)(GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glUniform1uiEXT)(GLint,GLuint); void (WINE_GLAPI *p_glUniform1uiv)(GLint,GLsizei,const GLuint*); @@ -2373,13 +2404,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glUniform2fv)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform2fvARB)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform2i)(GLint,GLint,GLint); + void (WINE_GLAPI *p_glUniform2i64ARB)(GLint,GLint64,GLint64); void (WINE_GLAPI *p_glUniform2i64NV)(GLint,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glUniform2i64vARB)(GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glUniform2i64vNV)(GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glUniform2iARB)(GLint,GLint,GLint); void (WINE_GLAPI *p_glUniform2iv)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform2ivARB)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform2ui)(GLint,GLuint,GLuint); + void (WINE_GLAPI *p_glUniform2ui64ARB)(GLint,GLuint64,GLuint64); void (WINE_GLAPI *p_glUniform2ui64NV)(GLint,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glUniform2ui64vARB)(GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glUniform2ui64vNV)(GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glUniform2uiEXT)(GLint,GLuint,GLuint); void (WINE_GLAPI *p_glUniform2uiv)(GLint,GLsizei,const GLuint*); @@ -2391,13 +2426,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glUniform3fv)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform3fvARB)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform3i)(GLint,GLint,GLint,GLint); + void (WINE_GLAPI *p_glUniform3i64ARB)(GLint,GLint64,GLint64,GLint64); void (WINE_GLAPI *p_glUniform3i64NV)(GLint,GLint64EXT,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glUniform3i64vARB)(GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glUniform3i64vNV)(GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glUniform3iARB)(GLint,GLint,GLint,GLint); void (WINE_GLAPI *p_glUniform3iv)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform3ivARB)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform3ui)(GLint,GLuint,GLuint,GLuint); + void (WINE_GLAPI *p_glUniform3ui64ARB)(GLint,GLuint64,GLuint64,GLuint64); void (WINE_GLAPI *p_glUniform3ui64NV)(GLint,GLuint64EXT,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glUniform3ui64vARB)(GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glUniform3ui64vNV)(GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glUniform3uiEXT)(GLint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glUniform3uiv)(GLint,GLsizei,const GLuint*); @@ -2409,13 +2448,17 @@ struct opengl_funcs void (WINE_GLAPI *p_glUniform4fv)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform4fvARB)(GLint,GLsizei,const GLfloat*); void (WINE_GLAPI *p_glUniform4i)(GLint,GLint,GLint,GLint,GLint); + void (WINE_GLAPI *p_glUniform4i64ARB)(GLint,GLint64,GLint64,GLint64,GLint64); void (WINE_GLAPI *p_glUniform4i64NV)(GLint,GLint64EXT,GLint64EXT,GLint64EXT,GLint64EXT); + void (WINE_GLAPI *p_glUniform4i64vARB)(GLint,GLsizei,const GLint64*); void (WINE_GLAPI *p_glUniform4i64vNV)(GLint,GLsizei,const GLint64EXT*); void (WINE_GLAPI *p_glUniform4iARB)(GLint,GLint,GLint,GLint,GLint); void (WINE_GLAPI *p_glUniform4iv)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform4ivARB)(GLint,GLsizei,const GLint*); void (WINE_GLAPI *p_glUniform4ui)(GLint,GLuint,GLuint,GLuint,GLuint); + void (WINE_GLAPI *p_glUniform4ui64ARB)(GLint,GLuint64,GLuint64,GLuint64,GLuint64); void (WINE_GLAPI *p_glUniform4ui64NV)(GLint,GLuint64EXT,GLuint64EXT,GLuint64EXT,GLuint64EXT); + void (WINE_GLAPI *p_glUniform4ui64vARB)(GLint,GLsizei,const GLuint64*); void (WINE_GLAPI *p_glUniform4ui64vNV)(GLint,GLsizei,const GLuint64EXT*); void (WINE_GLAPI *p_glUniform4uiEXT)(GLint,GLuint,GLuint,GLuint,GLuint); void (WINE_GLAPI *p_glUniform4uiv)(GLint,GLsizei,const GLuint*); @@ -2897,14 +2940,16 @@ struct opengl_funcs BOOL (WINE_GLAPI *p_wglGetPixelFormatAttribivARB)(HDC,int,int,UINT,const int*,int*); int (WINE_GLAPI *p_wglGetSwapIntervalEXT)(void); BOOL (WINE_GLAPI *p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context *); + BOOL (WINE_GLAPI *p_wglQueryCurrentRendererIntegerWINE)(GLenum,GLuint *); + const GLchar * (WINE_GLAPI *p_wglQueryCurrentRendererStringWINE)(GLenum); BOOL (WINE_GLAPI *p_wglQueryPbufferARB)(struct wgl_pbuffer *,int,int*); + BOOL (WINE_GLAPI *p_wglQueryRendererIntegerWINE)(HDC,GLint,GLenum,GLuint *); + const GLchar * (WINE_GLAPI *p_wglQueryRendererStringWINE)(HDC,GLint,GLenum); int (WINE_GLAPI *p_wglReleasePbufferDCARB)(struct wgl_pbuffer *,HDC); BOOL (WINE_GLAPI *p_wglReleaseTexImageARB)(struct wgl_pbuffer *,int); BOOL (WINE_GLAPI *p_wglSetPbufferAttribARB)(struct wgl_pbuffer *,const int*); BOOL (WINE_GLAPI *p_wglSetPixelFormatWINE)(HDC,int); BOOL (WINE_GLAPI *p_wglSwapIntervalEXT)(int); - BOOL (WINE_GLAPI *p_wglGetPCIInfoWINE)(unsigned int *, unsigned int *); - BOOL (WINE_GLAPI *p_wglGetMemoryInfoWINE)(unsigned int *); } ext; }; diff --git a/reactos/sdk/include/reactos/wine/wined3d.h b/reactos/sdk/include/reactos/wine/wined3d.h index 007ef6e0eb5..7025bc0db25 100644 --- a/reactos/sdk/include/reactos/wine/wined3d.h +++ b/reactos/sdk/include/reactos/wine/wined3d.h @@ -46,8 +46,6 @@ #define WINED3DERR_INVALIDCALL MAKE_WINED3DHRESULT(2156) #define WINEDDERR_NOTAOVERLAYSURFACE MAKE_WINED3DHRESULT(580) #define WINEDDERR_NOTLOCKED MAKE_WINED3DHRESULT(584) -#define WINEDDERR_NODC MAKE_WINED3DHRESULT(586) -#define WINEDDERR_DCALREADYCREATED MAKE_WINED3DHRESULT(620) #define WINEDDERR_SURFACEBUSY MAKE_WINED3DHRESULT(430) #define WINEDDERR_INVALIDRECT MAKE_WINED3DHRESULT(150) #define WINEDDERR_OVERLAYNOTVISIBLE MAKE_WINED3DHRESULT(577) @@ -74,6 +72,7 @@ enum wined3d_primitive_type WINED3D_PT_LINESTRIP_ADJ = 11, WINED3D_PT_TRIANGLELIST_ADJ = 12, WINED3D_PT_TRIANGLESTRIP_ADJ = 13, + WINED3D_PT_PATCH = 14, }; enum wined3d_device_type @@ -115,6 +114,8 @@ enum wined3d_format_id WINED3DFMT_R5G5_SNORM_L6_UNORM, WINED3DFMT_R8G8_SNORM_L8X8_UNORM, WINED3DFMT_R10G11B11_SNORM, + WINED3DFMT_R10G10B10X2_UINT, + WINED3DFMT_R10G10B10X2_SNORM, WINED3DFMT_R10G10B10_SNORM_A2_UNORM, WINED3DFMT_D16_LOCKABLE, WINED3DFMT_D32_UNORM, @@ -123,7 +124,6 @@ enum wined3d_format_id WINED3DFMT_S4X4_UINT_D24_UNORM, WINED3DFMT_L16_UNORM, WINED3DFMT_S8_UINT_D24_FLOAT, - WINED3DFMT_VERTEXDATA, WINED3DFMT_R8G8_SNORM_Cx, WINED3DFMT_R32G32B32A32_TYPELESS, WINED3DFMT_R32G32B32A32_FLOAT, @@ -151,6 +151,7 @@ enum wined3d_format_id WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_R10G10B10A2_UINT, WINED3DFMT_R10G10B10A2_SNORM, + WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM, WINED3DFMT_R11G11B10_FLOAT, WINED3DFMT_R8G8B8A8_TYPELESS, WINED3DFMT_R8G8B8A8_UNORM, @@ -218,6 +219,9 @@ enum wined3d_format_id WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_TYPELESS, WINED3DFMT_B8G8R8X8_UNORM_SRGB, + WINED3DFMT_BC6H_TYPELESS, + WINED3DFMT_BC6H_UF16, + WINED3DFMT_BC6H_SF16, WINED3DFMT_BC7_TYPELESS, WINED3DFMT_BC7_UNORM, WINED3DFMT_BC7_UNORM_SRGB, @@ -251,17 +255,17 @@ enum wined3d_format_id enum wined3d_render_state { - WINED3D_RS_ANTIALIAS = 2, /* d3d7 */ - WINED3D_RS_TEXTUREPERSPECTIVE = 4, /* d3d7 */ - WINED3D_RS_WRAPU = 5, /* d3d7 */ - WINED3D_RS_WRAPV = 6, /* d3d7 */ + WINED3D_RS_ANTIALIAS = 2, + WINED3D_RS_TEXTUREPERSPECTIVE = 4, + WINED3D_RS_WRAPU = 5, + WINED3D_RS_WRAPV = 6, WINED3D_RS_ZENABLE = 7, WINED3D_RS_FILLMODE = 8, WINED3D_RS_SHADEMODE = 9, - WINED3D_RS_LINEPATTERN = 10, /* d3d7, d3d8 */ - WINED3D_RS_MONOENABLE = 11, /* d3d7 */ - WINED3D_RS_ROP2 = 12, /* d3d7 */ - WINED3D_RS_PLANEMASK = 13, /* d3d7 */ + WINED3D_RS_LINEPATTERN = 10, + WINED3D_RS_MONOENABLE = 11, + WINED3D_RS_ROP2 = 12, + WINED3D_RS_PLANEMASK = 13, WINED3D_RS_ZWRITEENABLE = 14, WINED3D_RS_ALPHATESTENABLE = 15, WINED3D_RS_LASTPIXEL = 16, @@ -275,23 +279,23 @@ enum wined3d_render_state WINED3D_RS_ALPHABLENDENABLE = 27, WINED3D_RS_FOGENABLE = 28, WINED3D_RS_SPECULARENABLE = 29, - WINED3D_RS_ZVISIBLE = 30, /* d3d7, d3d8 */ - WINED3D_RS_SUBPIXEL = 31, /* d3d7 */ - WINED3D_RS_SUBPIXELX = 32, /* d3d7 */ - WINED3D_RS_STIPPLEDALPHA = 33, /* d3d7 */ + WINED3D_RS_ZVISIBLE = 30, + WINED3D_RS_SUBPIXEL = 31, + WINED3D_RS_SUBPIXELX = 32, + WINED3D_RS_STIPPLEDALPHA = 33, WINED3D_RS_FOGCOLOR = 34, WINED3D_RS_FOGTABLEMODE = 35, WINED3D_RS_FOGSTART = 36, WINED3D_RS_FOGEND = 37, WINED3D_RS_FOGDENSITY = 38, - WINED3D_RS_STIPPLEENABLE = 39, /* d3d7 */ - WINED3D_RS_EDGEANTIALIAS = 40, /* d3d7, d3d8 */ - WINED3D_RS_COLORKEYENABLE = 41, /* d3d7 */ - WINED3D_RS_MIPMAPLODBIAS = 46, /* d3d7 */ + WINED3D_RS_STIPPLEENABLE = 39, + WINED3D_RS_EDGEANTIALIAS = 40, + WINED3D_RS_COLORKEYENABLE = 41, + WINED3D_RS_MIPMAPLODBIAS = 46, WINED3D_RS_RANGEFOGENABLE = 48, - WINED3D_RS_ANISOTROPY = 49, /* d3d7 */ - WINED3D_RS_FLUSHBATCH = 50, /* d3d7 */ - WINED3D_RS_TRANSLUCENTSORTINDEPENDENT = 51, /* d3d7 */ + WINED3D_RS_ANISOTROPY = 49, + WINED3D_RS_FLUSHBATCH = 50, + WINED3D_RS_TRANSLUCENTSORTINDEPENDENT = 51, WINED3D_RS_STENCILENABLE = 52, WINED3D_RS_STENCILFAIL = 53, WINED3D_RS_STENCILZFAIL = 54, @@ -311,20 +315,20 @@ enum wined3d_render_state WINED3D_RS_WRAP7 = 135, WINED3D_RS_CLIPPING = 136, WINED3D_RS_LIGHTING = 137, - WINED3D_RS_EXTENTS = 138, /* d3d7 */ + WINED3D_RS_EXTENTS = 138, WINED3D_RS_AMBIENT = 139, WINED3D_RS_FOGVERTEXMODE = 140, WINED3D_RS_COLORVERTEX = 141, WINED3D_RS_LOCALVIEWER = 142, WINED3D_RS_NORMALIZENORMALS = 143, - WINED3D_RS_COLORKEYBLENDENABLE = 144, /* d3d7 */ + WINED3D_RS_COLORKEYBLENDENABLE = 144, WINED3D_RS_DIFFUSEMATERIALSOURCE = 145, WINED3D_RS_SPECULARMATERIALSOURCE = 146, WINED3D_RS_AMBIENTMATERIALSOURCE = 147, WINED3D_RS_EMISSIVEMATERIALSOURCE = 148, WINED3D_RS_VERTEXBLEND = 151, WINED3D_RS_CLIPPLANEENABLE = 152, - WINED3D_RS_SOFTWAREVERTEXPROCESSING = 153, /* d3d8 */ + WINED3D_RS_SOFTWAREVERTEXPROCESSING = 153, WINED3D_RS_POINTSIZE = 154, WINED3D_RS_POINTSIZE_MIN = 155, WINED3D_RS_POINTSPRITEENABLE = 156, @@ -335,7 +339,7 @@ enum wined3d_render_state WINED3D_RS_MULTISAMPLEANTIALIAS = 161, WINED3D_RS_MULTISAMPLEMASK = 162, WINED3D_RS_PATCHEDGESTYLE = 163, - WINED3D_RS_PATCHSEGMENTS = 164, /* d3d8 */ + WINED3D_RS_PATCHSEGMENTS = 164, WINED3D_RS_DEBUGMONITORTOKEN = 165, WINED3D_RS_POINTSIZE_MAX = 166, WINED3D_RS_INDEXEDVERTEXBLENDENABLE = 167, @@ -355,10 +359,10 @@ enum wined3d_render_state WINED3D_RS_ADAPTIVETESS_W = 183, WINED3D_RS_ENABLEADAPTIVETESSELLATION = 184, WINED3D_RS_TWOSIDEDSTENCILMODE = 185, - WINED3D_RS_CCW_STENCILFAIL = 186, - WINED3D_RS_CCW_STENCILZFAIL = 187, - WINED3D_RS_CCW_STENCILPASS = 188, - WINED3D_RS_CCW_STENCILFUNC = 189, + WINED3D_RS_BACK_STENCILFAIL = 186, + WINED3D_RS_BACK_STENCILZFAIL = 187, + WINED3D_RS_BACK_STENCILPASS = 188, + WINED3D_RS_BACK_STENCILFUNC = 189, WINED3D_RS_COLORWRITEENABLE1 = 190, WINED3D_RS_COLORWRITEENABLE2 = 191, WINED3D_RS_COLORWRITEENABLE3 = 192, @@ -397,6 +401,10 @@ enum wined3d_blend WINED3D_BLEND_BOTHINVSRCALPHA = 13, WINED3D_BLEND_BLENDFACTOR = 14, WINED3D_BLEND_INVBLENDFACTOR = 15, + WINED3D_BLEND_SRC1COLOR = 16, + WINED3D_BLEND_INVSRC1COLOR = 17, + WINED3D_BLEND_SRC1ALPHA = 18, + WINED3D_BLEND_INVSRC1ALPHA = 19, }; enum wined3d_blend_op @@ -462,8 +470,8 @@ enum wined3d_fill_mode enum wined3d_cull { WINED3D_CULL_NONE = 1, - WINED3D_CULL_CW = 2, - WINED3D_CULL_CCW = 3, + WINED3D_CULL_FRONT = 2, + WINED3D_CULL_BACK = 3, }; enum wined3d_stencil_op @@ -662,11 +670,10 @@ enum wined3d_texture_filter_type enum wined3d_resource_type { - WINED3D_RTYPE_SURFACE = 1, - WINED3D_RTYPE_VOLUME = 2, - WINED3D_RTYPE_BUFFER = 3, - WINED3D_RTYPE_TEXTURE_2D = 4, - WINED3D_RTYPE_TEXTURE_3D = 5, + WINED3D_RTYPE_BUFFER = 1, + WINED3D_RTYPE_TEXTURE_1D = 2, + WINED3D_RTYPE_TEXTURE_2D = 3, + WINED3D_RTYPE_TEXTURE_3D = 4, }; enum wined3d_pool @@ -679,23 +686,32 @@ enum wined3d_pool enum wined3d_query_type { - WINED3D_QUERY_TYPE_PIPELINE_STATISTICS = 1, - WINED3D_QUERY_TYPE_SO_STATISTICS = 2, - WINED3D_QUERY_TYPE_SO_OVERFLOW = 3, - WINED3D_QUERY_TYPE_VCACHE = 4, - WINED3D_QUERY_TYPE_RESOURCE_MANAGER = 5, - WINED3D_QUERY_TYPE_VERTEX_STATS = 6, - WINED3D_QUERY_TYPE_EVENT = 8, - WINED3D_QUERY_TYPE_OCCLUSION = 9, - WINED3D_QUERY_TYPE_TIMESTAMP = 10, - WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT = 11, - WINED3D_QUERY_TYPE_TIMESTAMP_FREQ = 12, - WINED3D_QUERY_TYPE_PIPELINE_TIMINGS = 13, - WINED3D_QUERY_TYPE_INTERFACE_TIMINGS = 14, - WINED3D_QUERY_TYPE_VERTEX_TIMINGS = 15, - WINED3D_QUERY_TYPE_PIXEL_TIMINGS = 16, - WINED3D_QUERY_TYPE_BANDWIDTH_TIMINGS = 17, - WINED3D_QUERY_TYPE_CACHE_UTILIZATION = 18 + WINED3D_QUERY_TYPE_VCACHE = 4, + WINED3D_QUERY_TYPE_RESOURCE_MANAGER = 5, + WINED3D_QUERY_TYPE_VERTEX_STATS = 6, + WINED3D_QUERY_TYPE_EVENT = 8, + WINED3D_QUERY_TYPE_OCCLUSION = 9, + WINED3D_QUERY_TYPE_TIMESTAMP = 10, + WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT = 11, + WINED3D_QUERY_TYPE_TIMESTAMP_FREQ = 12, + WINED3D_QUERY_TYPE_PIPELINE_TIMINGS = 13, + WINED3D_QUERY_TYPE_INTERFACE_TIMINGS = 14, + WINED3D_QUERY_TYPE_VERTEX_TIMINGS = 15, + WINED3D_QUERY_TYPE_PIXEL_TIMINGS = 16, + WINED3D_QUERY_TYPE_BANDWIDTH_TIMINGS = 17, + WINED3D_QUERY_TYPE_CACHE_UTILIZATION = 18, + WINED3D_QUERY_TYPE_MEMORY_PRESSURE = 19, + WINED3D_QUERY_TYPE_PIPELINE_STATISTICS = 20, + WINED3D_QUERY_TYPE_SO_STATISTICS = 21, + WINED3D_QUERY_TYPE_SO_OVERFLOW = 22, + WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0 = 23, + WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM0 = 24, + WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1 = 25, + WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM1 = 26, + WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2 = 27, + WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM2 = 28, + WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3 = 29, + WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM3 = 30, }; struct wined3d_query_data_timestamp_disjoint @@ -704,6 +720,27 @@ struct wined3d_query_data_timestamp_disjoint BOOL disjoint; }; +struct wined3d_query_data_so_statistics +{ + UINT64 primitives_written; + UINT64 primitives_generated; +}; + +struct wined3d_query_data_pipeline_statistics +{ + UINT64 ia_vertices; + UINT64 ia_primitives; + UINT64 vs_invocations; + UINT64 gs_invocations; + UINT64 gs_primitives; + UINT64 c_invocations; + UINT64 c_primitives; + UINT64 ps_invocations; + UINT64 hs_invocations; + UINT64 ds_invocations; + UINT64 cs_invocations; +}; + #define WINED3DISSUE_BEGIN (1u << 1) #define WINED3DISSUE_END (1u << 0) #define WINED3DGETDATA_FLUSH (1u << 0) @@ -747,21 +784,30 @@ enum wined3d_decl_usage enum wined3d_sysval_semantic { - WINED3D_SV_POSITION = 1, - WINED3D_SV_PRIMITIVEID = 7, - WINED3D_SV_INSTANCEID = 8, - WINED3D_SV_ISFRONTFACE = 9, - WINED3D_SV_SAMPLEINDEX = 10, + WINED3D_SV_POSITION = 1, + WINED3D_SV_CLIP_DISTANCE = 2, + WINED3D_SV_CULL_DISTANCE = 3, + WINED3D_SV_RENDER_TARGET_ARRAY_INDEX = 4, + WINED3D_SV_VIEWPORT_ARRAY_INDEX = 5, + WINED3D_SV_VERTEX_ID = 6, + WINED3D_SV_PRIMITIVE_ID = 7, + WINED3D_SV_INSTANCE_ID = 8, + WINED3D_SV_IS_FRONT_FACE = 9, + WINED3D_SV_SAMPLE_INDEX = 10, + WINED3D_SV_TESS_FACTOR_QUADEDGE = 11, + WINED3D_SV_TESS_FACTOR_QUADINT = 12, + WINED3D_SV_TESS_FACTOR_TRIEDGE = 13, + WINED3D_SV_TESS_FACTOR_TRIINT = 14, + WINED3D_SV_TESS_FACTOR_LINEDET = 15, + WINED3D_SV_TESS_FACTOR_LINEDEN = 16, +}; - WINED3D_SV_DEPTH = 0xffffffff, - WINED3D_SV_TARGET0 = 0, - WINED3D_SV_TARGET1 = 1, - WINED3D_SV_TARGET2 = 2, - WINED3D_SV_TARGET3 = 3, - WINED3D_SV_TARGET4 = 4, - WINED3D_SV_TARGET5 = 5, - WINED3D_SV_TARGET6 = 6, - WINED3D_SV_TARGET7 = 7, +enum wined3d_component_type +{ + WINED3D_TYPE_UNKNOWN = 0, + WINED3D_TYPE_UINT = 1, + WINED3D_TYPE_INT = 2, + WINED3D_TYPE_FLOAT = 3, }; enum wined3d_scanline_ordering @@ -780,6 +826,43 @@ enum wined3d_display_rotation WINED3D_DISPLAY_ROTATION_270 = 4, }; +enum wined3d_shader_byte_code_format +{ + WINED3D_SHADER_BYTE_CODE_FORMAT_SM1 = 0, + WINED3D_SHADER_BYTE_CODE_FORMAT_SM4 = 1, +}; + +enum wined3d_format_support +{ + WINED3D_FORMAT_SUPPORT_BUFFER = 0x0000001, + WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x0000002, + WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x0000004, + WINED3D_FORMAT_SUPPORT_SO_BUFFER = 0x0000008, + WINED3D_FORMAT_SUPPORT_TEXTURE1D = 0x0000010, + WINED3D_FORMAT_SUPPORT_TEXTURE2D = 0x0000020, + WINED3D_FORMAT_SUPPORT_TEXTURE3D = 0x0000040, + WINED3D_FORMAT_SUPPORT_TEXTURECUBE = 0x0000080, + WINED3D_FORMAT_SUPPORT_SHADER_LOAD = 0x0000100, + WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE = 0x0000200, + WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x0000400, + WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x0000800, + WINED3D_FORMAT_SUPPORT_MIP = 0x0001000, + WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN = 0x0002000, + WINED3D_FORMAT_SUPPORT_RENDER_TARGET = 0x0004000, + WINED3D_FORMAT_SUPPORT_BLENDABLE = 0x0008000, + WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL = 0x0010000, + WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE = 0x0020000, + WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x0040000, + WINED3D_FORMAT_SUPPORT_DISPLAY = 0x0080000, + WINED3D_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x0100000, + WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x0200000, + WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x0400000, + WINED3D_FORMAT_SUPPORT_SHADER_GATHER = 0x0800000, + WINED3D_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x1000000, + WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW = 0x2000000, + WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x4000000, +}; + #define WINED3DCOLORWRITEENABLE_RED (1u << 0) #define WINED3DCOLORWRITEENABLE_GREEN (1u << 1) #define WINED3DCOLORWRITEENABLE_BLUE (1u << 2) @@ -805,15 +888,28 @@ enum wined3d_display_rotation #define WINED3DTA_COMPLEMENT 0x00000010 #define WINED3DTA_ALPHAREPLICATE 0x00000020 -#define WINED3DPRESENTFLAG_LOCKABLE_BACKBUFFER 0x00000001 -#define WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 0x00000002 -#define WINED3DPRESENTFLAG_DEVICECLIP 0x00000004 -#define WINED3DPRESENTFLAG_VIDEO 0x00000010 -#define WINED3DPRESENTFLAG_NOAUTOROTATE 0x00000020 -#define WINED3DPRESENTFLAG_UNPRUNEDMODE 0x00000040 +#define WINED3D_SWAPCHAIN_LOCKABLE_BACKBUFFER 0x00000001u +#define WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL 0x00000002u +#define WINED3D_SWAPCHAIN_DEVICECLIP 0x00000004u +#define WINED3D_SWAPCHAIN_VIDEO 0x00000010u +#define WINED3D_SWAPCHAIN_NOAUTOROTATE 0x00000020u +#define WINED3D_SWAPCHAIN_UNPRUNEDMODE 0x00000040u +#define WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH 0x00001000u +#define WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE 0x00002000u +#define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u +#define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u #define WINED3DDP_MAXTEXCOORD 8 +#define WINED3D_BIND_VERTEX_BUFFER 0x00000001 +#define WINED3D_BIND_INDEX_BUFFER 0x00000002 +#define WINED3D_BIND_CONSTANT_BUFFER 0x00000004 +#define WINED3D_BIND_SHADER_RESOURCE 0x00000008 +#define WINED3D_BIND_STREAM_OUTPUT 0x00000010 +#define WINED3D_BIND_RENDER_TARGET 0x00000020 +#define WINED3D_BIND_DEPTH_STENCIL 0x00000040 +#define WINED3D_BIND_UNORDERED_ACCESS 0x00000080 + #define WINED3DUSAGE_RENDERTARGET 0x00000001 #define WINED3DUSAGE_DEPTHSTENCIL 0x00000002 #define WINED3DUSAGE_WRITEONLY 0x00000008 @@ -831,6 +927,7 @@ enum wined3d_display_rotation #define WINED3DUSAGE_TEXTAPI 0x10000000 #define WINED3DUSAGE_MASK 0x10007fff +#define WINED3DUSAGE_PRIVATE 0x00400000 #define WINED3DUSAGE_LEGACY_CUBEMAP 0x00800000 #define WINED3DUSAGE_TEXTURE 0x01000000 #define WINED3DUSAGE_OWNDC 0x02000000 @@ -1238,6 +1335,9 @@ enum wined3d_display_rotation #define WINED3D_PIXEL_CENTER_INTEGER 0x00000080 #define WINED3D_LEGACY_FFP_LIGHTING 0x00000100 #define WINED3D_SRGB_READ_WRITE_CONTROL 0x00000200 +#define WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR 0x00000400 +#define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 +#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 #define WINED3D_RESZ_CODE 0x7fa05000 @@ -1266,18 +1366,16 @@ enum wined3d_display_rotation /* add dwZBufferBaseDest to every source z value before compare */ #define WINEDDBLTFX_ZBUFFERBASEDEST 0x00000100 -#define WINED3D_BLT_ASYNC 0x00000200 -#define WINED3D_BLT_COLOR_FILL 0x00000400 #define WINED3D_BLT_FX 0x00000800 #define WINED3D_BLT_DST_CKEY 0x00002000 #define WINED3D_BLT_DST_CKEY_OVERRIDE 0x00004000 #define WINED3D_BLT_SRC_CKEY 0x00008000 #define WINED3D_BLT_SRC_CKEY_OVERRIDE 0x00010000 #define WINED3D_BLT_WAIT 0x01000000 -#define WINED3D_BLT_DEPTH_FILL 0x02000000 #define WINED3D_BLT_DO_NOT_WAIT 0x08000000 +#define WINED3D_BLT_SYNCHRONOUS 0x40000000 #define WINED3D_BLT_ALPHA_TEST 0x80000000 -#define WINED3D_BLT_MASK 0x8b01ee00 +#define WINED3D_BLT_MASK 0x0901e800 /* dwFlags for GetBltStatus */ #define WINEDDGBS_CANBLT 0x00000001 @@ -1468,13 +1566,24 @@ enum wined3d_display_rotation #define WINED3D_TEXTURE_CREATE_MAPPABLE 0x00000001 #define WINED3D_TEXTURE_CREATE_DISCARD 0x00000002 -#define WINED3D_TEXTURE_CREATE_PIN_SYSMEM 0x00000004 +#define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004 +#define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008 #define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff #define WINED3D_OUTPUT_SLOT_SEMANTIC 0xffffffff #define WINED3D_OUTPUT_SLOT_UNUSED 0xfffffffe +#define WINED3D_MAX_STREAM_OUTPUT_BUFFERS 4 +#define WINED3D_STREAM_OUTPUT_GAP 0xffffffff +#define WINED3D_NO_RASTERIZER_STREAM 0xffffffff + +#define WINED3D_VIEW_BUFFER_RAW 0x00000001 +#define WINED3D_VIEW_BUFFER_APPEND 0x00000002 +#define WINED3D_VIEW_BUFFER_COUNTER 0x00000004 +#define WINED3D_VIEW_TEXTURE_CUBE 0x00000008 +#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010 + struct wined3d_display_mode { UINT width; @@ -1507,6 +1616,30 @@ struct wined3d_vec4 float w; }; +struct wined3d_dvec4 +{ + double x; + double y; + double z; + double w; +}; + +struct wined3d_ivec4 +{ + int x; + int y; + int z; + int w; +}; + +struct wined3d_uvec4 +{ + unsigned int x; + unsigned int y; + unsigned int z; + unsigned int w; +}; + struct wined3d_matrix { float _11, _12, _13, _14; @@ -1543,10 +1676,10 @@ struct wined3d_material struct wined3d_viewport { - UINT x; - UINT y; - UINT width; - UINT height; + float x; + float y; + float width; + float height; float min_z; float max_z; }; @@ -1635,6 +1768,19 @@ struct wined3d_resource_desc UINT size; }; +struct wined3d_sub_resource_desc +{ + enum wined3d_format_id format; + enum wined3d_multisample_type multisample_type; + UINT multisample_quality; + DWORD usage; + enum wined3d_pool pool; + UINT width; + UINT height; + UINT depth; + UINT size; +}; + struct wined3d_clip_status { DWORD clip_union; @@ -1681,6 +1827,13 @@ struct wined3d_map_desc void *data; }; +struct wined3d_map_info +{ + UINT row_pitch; + UINT slice_pitch; + UINT size; +}; + struct wined3d_sub_resource_data { const void *data; @@ -1825,6 +1978,8 @@ typedef struct _WINED3DCAPS DWORD Reserved3; struct wined3d_ddraw_caps ddraw_caps; + + BOOL shader_double_precision; } WINED3DCAPS; struct wined3d_color_key @@ -1838,37 +1993,23 @@ struct wined3d_color_key struct wined3d_blt_fx { DWORD fx; - DWORD fill_color; struct wined3d_color_key dst_color_key; struct wined3d_color_key src_color_key; }; struct wined3d_buffer_desc { - UINT byte_width; + unsigned int byte_width; DWORD usage; - UINT bind_flags; - UINT cpu_access_flags; - UINT misc_flags; + unsigned int bind_flags; + unsigned int cpu_access_flags; + unsigned int misc_flags; + unsigned int structure_byte_stride; }; -struct wined3d_rendertarget_view_desc +struct wined3d_rasterizer_state_desc { - enum wined3d_format_id format_id; - union - { - struct - { - unsigned int start_idx; - unsigned int count; - } buffer; - struct - { - unsigned int level_idx; - unsigned int layer_idx; - unsigned int layer_count; - } texture; - } u; + BOOL front_ccw; }; struct wined3d_sampler_desc @@ -1883,6 +2024,7 @@ struct wined3d_sampler_desc float lod_bias; float min_lod; float max_lod; + unsigned int mip_base_level; unsigned int max_anisotropy; BOOL compare; enum wined3d_cmp_func comparison_func; @@ -1892,10 +2034,11 @@ struct wined3d_sampler_desc struct wined3d_shader_signature_element { const char *semantic_name; - UINT semantic_idx; + unsigned int semantic_idx; + unsigned int stream_idx; enum wined3d_sysval_semantic sysval_semantic; - DWORD component_type; - UINT register_idx; + enum wined3d_component_type component_type; + unsigned int register_idx; DWORD mask; }; @@ -1908,11 +2051,53 @@ struct wined3d_shader_signature struct wined3d_shader_desc { const DWORD *byte_code; - const struct wined3d_shader_signature *input_signature; - const struct wined3d_shader_signature *output_signature; + size_t byte_code_size; + enum wined3d_shader_byte_code_format format; + struct wined3d_shader_signature input_signature; + struct wined3d_shader_signature output_signature; + struct wined3d_shader_signature patch_constant_signature; unsigned int max_version; }; +struct wined3d_stream_output_element +{ + unsigned int stream_idx; + unsigned int register_idx; + BYTE component_idx; + BYTE component_count; + BYTE output_slot; +}; + +struct wined3d_stream_output_desc +{ + struct wined3d_stream_output_element *elements; + unsigned int element_count; + unsigned int buffer_strides[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; + unsigned int buffer_stride_count; + unsigned int rasterizer_stream_idx; +}; + +struct wined3d_view_desc +{ + enum wined3d_format_id format_id; + unsigned int flags; + union + { + struct + { + unsigned int start_idx; + unsigned int count; + } buffer; + struct + { + unsigned int level_idx; + unsigned int level_count; + unsigned int layer_idx; + unsigned int layer_count; + } texture; + } u; +}; + struct wined3d_output_desc { WCHAR device_name[CCHDEVICENAME]; @@ -1932,6 +2117,7 @@ struct wined3d_buffer; struct wined3d_device; struct wined3d_palette; struct wined3d_query; +struct wined3d_rasterizer_state; struct wined3d_rendertarget_view; struct wined3d_resource; struct wined3d_sampler; @@ -1940,6 +2126,7 @@ struct wined3d_shader_resource_view; struct wined3d_stateblock; struct wined3d_swapchain; struct wined3d_texture; +struct wined3d_unordered_access_view; struct wined3d_vertex_declaration; struct wined3d_device_parent @@ -1959,7 +2146,7 @@ struct wined3d_device_parent_ops struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops); HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent, - const struct wined3d_resource_desc *desc, struct wined3d_texture **texture); + const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture); HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent, struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain); }; @@ -1999,6 +2186,8 @@ HRESULT __cdecl wined3d_check_device_format(const struct wined3d *wined3d, UINT HRESULT __cdecl wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id source_format_id, enum wined3d_format_id target_format_id); +void CDECL wined3d_check_device_format_support(struct wined3d_device *device, + enum wined3d_format_id check_format_id, UINT *support); HRESULT __cdecl wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed, enum wined3d_multisample_type multisample_type, DWORD *quality_levels); @@ -2010,6 +2199,8 @@ ULONG __cdecl wined3d_decref(struct wined3d *wined3d); HRESULT __cdecl wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering, UINT mode_idx, struct wined3d_display_mode *mode); +HRESULT __cdecl wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d, + unsigned int adapter_idx, struct wined3d_display_mode *mode); UINT __cdecl wined3d_get_adapter_count(const struct wined3d *wined3d); HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation); @@ -2041,9 +2232,6 @@ ULONG __cdecl wined3d_buffer_decref(struct wined3d_buffer *buffer); void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer); struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer); ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer); -HRESULT __cdecl wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags); -void __cdecl wined3d_buffer_preload(struct wined3d_buffer *buffer); -void __cdecl wined3d_buffer_unmap(struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window); HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device); @@ -2051,7 +2239,10 @@ HRESULT __cdecl wined3d_device_begin_stateblock(struct wined3d_device *device); HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float z, DWORD stencil); HRESULT __cdecl wined3d_device_clear_rendertarget_view(struct wined3d_device *device, - struct wined3d_rendertarget_view *view, const RECT *rect, const struct wined3d_color *color); + struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags, + const struct wined3d_color *color, float depth, DWORD stencil); +void __cdecl wined3d_device_clear_unordered_access_view_uint(struct wined3d_device *device, + struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value); void __cdecl wined3d_device_copy_resource(struct wined3d_device *device, struct wined3d_resource *dst_resource, struct wined3d_resource *src_resource); HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *device, @@ -2062,6 +2253,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent, struct wined3d_device **device); ULONG __cdecl wined3d_device_decref(struct wined3d_device *device); +void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device, + unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z); HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count); void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device, UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count); @@ -2077,12 +2270,24 @@ HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *devic UINT plane_idx, struct wined3d_vec4 *plane); HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device, struct wined3d_clip_status *clip_status); +struct wined3d_shader * __cdecl wined3d_device_get_compute_shader(const struct wined3d_device *device); void __cdecl wined3d_device_get_creation_parameters(const struct wined3d_device *device, struct wined3d_device_creation_parameters *creation_parameters); +struct wined3d_buffer * __cdecl wined3d_device_get_cs_cb(const struct wined3d_device *device, unsigned int idx); +struct wined3d_shader_resource_view * __cdecl wined3d_device_get_cs_resource_view(const struct wined3d_device *device, + unsigned int idx); +struct wined3d_sampler * __cdecl wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx); +struct wined3d_unordered_access_view * __cdecl wined3d_device_get_cs_uav(const struct wined3d_device *device, + unsigned int idx); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_depth_stencil_view(const struct wined3d_device *device); HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps); HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation); +struct wined3d_shader * __cdecl wined3d_device_get_domain_shader(const struct wined3d_device *device); +struct wined3d_buffer * __cdecl wined3d_device_get_ds_cb(const struct wined3d_device *device, unsigned int idx); +struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ds_resource_view(const struct wined3d_device *device, + unsigned int idx); +struct wined3d_sampler * __cdecl wined3d_device_get_ds_sampler(const struct wined3d_device *device, unsigned int idx); void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_gamma_ramp *ramp); struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device); @@ -2090,8 +2295,13 @@ struct wined3d_buffer * __cdecl wined3d_device_get_gs_cb(const struct wined3d_de struct wined3d_shader_resource_view * __cdecl wined3d_device_get_gs_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_gs_sampler(const struct wined3d_device *device, UINT idx); +struct wined3d_buffer * __cdecl wined3d_device_get_hs_cb(const struct wined3d_device *device, unsigned int idx); +struct wined3d_shader_resource_view * __cdecl wined3d_device_get_hs_resource_view(const struct wined3d_device *device, + unsigned int idx); +struct wined3d_sampler * __cdecl wined3d_device_get_hs_sampler(const struct wined3d_device *device, unsigned int idx); +struct wined3d_shader * __cdecl wined3d_device_get_hull_shader(const struct wined3d_device *device); struct wined3d_buffer * __cdecl wined3d_device_get_index_buffer(const struct wined3d_device *device, - enum wined3d_format_id *format); + enum wined3d_format_id *format, unsigned int *offset); HRESULT __cdecl wined3d_device_get_light(const struct wined3d_device *device, UINT light_idx, struct wined3d_light *light); HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable); @@ -2100,19 +2310,20 @@ float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device); struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value); void __cdecl wined3d_device_get_primitive_type(const struct wined3d_device *device, - enum wined3d_primitive_type *primitive_topology); + enum wined3d_primitive_type *primitive_topology, unsigned int *patch_vertex_count); struct wined3d_buffer * __cdecl wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_ps_consts_b(const struct wined3d_device *device, - UINT start_register, BOOL *constants, UINT bool_count); + unsigned int start_idx, unsigned int count, BOOL *constants); HRESULT __cdecl wined3d_device_get_ps_consts_f(const struct wined3d_device *device, - UINT start_register, float *constants, UINT vector4f_count); + unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants); HRESULT __cdecl wined3d_device_get_ps_consts_i(const struct wined3d_device *device, - UINT start_register, int *constants, UINT vector4i_count); + unsigned int start_idx, unsigned int count, struct wined3d_ivec4 *constants); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ps_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_ps_sampler(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_raster_status(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_raster_status *raster_status); +struct wined3d_rasterizer_state * __cdecl wined3d_device_get_rasterizer_state(struct wined3d_device *device); DWORD __cdecl wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view(const struct wined3d_device *device, unsigned int view_idx); @@ -2134,16 +2345,18 @@ DWORD __cdecl wined3d_device_get_texture_stage_state(const struct wined3d_device UINT stage, enum wined3d_texture_stage_state state); void __cdecl wined3d_device_get_transform(const struct wined3d_device *device, enum wined3d_transform_state state, struct wined3d_matrix *matrix); +struct wined3d_unordered_access_view * __cdecl wined3d_device_get_unordered_access_view( + const struct wined3d_device *device, unsigned int idx); struct wined3d_vertex_declaration * __cdecl wined3d_device_get_vertex_declaration(const struct wined3d_device *device); struct wined3d_shader * __cdecl wined3d_device_get_vertex_shader(const struct wined3d_device *device); void __cdecl wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport); struct wined3d_buffer * __cdecl wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_vs_consts_b(const struct wined3d_device *device, - UINT start_register, BOOL *constants, UINT bool_count); + unsigned int start_idx, unsigned int count, BOOL *constants); HRESULT __cdecl wined3d_device_get_vs_consts_f(const struct wined3d_device *device, - UINT start_register, float *constants, UINT vector4f_count); + unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants); HRESULT __cdecl wined3d_device_get_vs_consts_i(const struct wined3d_device *device, - UINT start_register, int *constants, UINT vector4i_count); + unsigned int start_idx, unsigned int count, struct wined3d_ivec4 *constants); struct wined3d_shader_resource_view * __cdecl wined3d_device_get_vs_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx); @@ -2160,12 +2373,21 @@ void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device); HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state); -void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window); +void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, + const RECT *window_rect); void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index); HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device, UINT plane_idx, const struct wined3d_vec4 *plane); HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device, const struct wined3d_clip_status *clip_status); +void __cdecl wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader); +void __cdecl wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_set_cs_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view); +void __cdecl wined3d_device_set_cs_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx, + struct wined3d_unordered_access_view *uav); void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device, int x_screen_space, int y_screen_space, DWORD flags); HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device, @@ -2173,6 +2395,12 @@ HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *devi void __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view); HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs); +void __cdecl wined3d_device_set_domain_shader(struct wined3d_device *device, struct wined3d_shader *shader); +void __cdecl wined3d_device_set_ds_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_set_ds_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view); +void __cdecl wined3d_device_set_ds_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler); void __cdecl wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp); void __cdecl wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader); @@ -2180,8 +2408,14 @@ void __cdecl wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, s void __cdecl wined3d_device_set_gs_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_set_hs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_set_hs_resource_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_shader_resource_view *view); +void __cdecl wined3d_device_set_hs_sampler(struct wined3d_device *device, + unsigned int idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_set_hull_shader(struct wined3d_device *device, struct wined3d_shader *shader); void __cdecl wined3d_device_set_index_buffer(struct wined3d_device *device, - struct wined3d_buffer *index_buffer, enum wined3d_format_id format_id); + struct wined3d_buffer *index_buffer, enum wined3d_format_id format_id, unsigned int offset); HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device, UINT light_idx, const struct wined3d_light *light); HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable); @@ -2192,17 +2426,19 @@ void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, stru void __cdecl wined3d_device_set_predication(struct wined3d_device *device, struct wined3d_query *predicate, BOOL value); void __cdecl wined3d_device_set_primitive_type(struct wined3d_device *device, - enum wined3d_primitive_type primitive_topology); + enum wined3d_primitive_type primitive_topology, unsigned int patch_vertex_count); void __cdecl wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_set_ps_consts_b(struct wined3d_device *device, - UINT start_register, const BOOL *constants, UINT bool_count); + unsigned int start_idx, unsigned int count, const BOOL *constants); HRESULT __cdecl wined3d_device_set_ps_consts_f(struct wined3d_device *device, - UINT start_register, const float *constants, UINT vector4f_count); + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants); HRESULT __cdecl wined3d_device_set_ps_consts_i(struct wined3d_device *device, - UINT start_register, const int *constants, UINT vector4i_count); + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants); void __cdecl wined3d_device_set_ps_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_set_rasterizer_state(struct wined3d_device *device, + struct wined3d_rasterizer_state *rasterizer_state); void __cdecl wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value); HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *device, @@ -2221,17 +2457,19 @@ void __cdecl wined3d_device_set_texture_stage_state(struct wined3d_device *devic UINT stage, enum wined3d_texture_stage_state state, DWORD value); void __cdecl wined3d_device_set_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix); +void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *device, + unsigned int idx, struct wined3d_unordered_access_view *uav); void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device, struct wined3d_vertex_declaration *declaration); void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader); void __cdecl wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport); void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer); HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device, - UINT start_register, const BOOL *constants, UINT bool_count); + unsigned int start_idx, unsigned int count, const BOOL *constants); HRESULT __cdecl wined3d_device_set_vs_consts_f(struct wined3d_device *device, - UINT start_register, const float *constants, UINT vector4f_count); + unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants); HRESULT __cdecl wined3d_device_set_vs_consts_i(struct wined3d_device *device, - UINT start_register, const int *constants, UINT vector4i_count); + unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants); void __cdecl wined3d_device_set_vs_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); @@ -2256,8 +2494,8 @@ ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette); HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries); -HRESULT __cdecl wined3d_query_create(struct wined3d_device *device, - enum wined3d_query_type type, void *parent, struct wined3d_query **query); +HRESULT __cdecl wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query); ULONG __cdecl wined3d_query_decref(struct wined3d_query *query); HRESULT __cdecl wined3d_query_get_data(struct wined3d_query *query, void *data, UINT data_size, DWORD flags); UINT __cdecl wined3d_query_get_data_size(const struct wined3d_query *query); @@ -2340,17 +2578,27 @@ static inline HRESULT wined3d_private_store_set_private_data(struct wined3d_priv return WINED3D_OK; } +HRESULT __cdecl wined3d_rasterizer_state_create(struct wined3d_device *device, + const struct wined3d_rasterizer_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_rasterizer_state **state); +ULONG __cdecl wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state); +void * __cdecl wined3d_rasterizer_state_get_parent(const struct wined3d_rasterizer_state *state); +ULONG __cdecl wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state); + void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc); void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource); DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource); +HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); +HRESULT __cdecl wined3d_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_info *info, DWORD flags); +void __cdecl wined3d_resource_preload(struct wined3d_resource *resource); void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority); -HRESULT __cdecl wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); -HRESULT __cdecl wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); +HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); -HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, +HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view); HRESULT __cdecl wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, @@ -2364,12 +2612,19 @@ ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent); HRESULT __cdecl wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, - void *parent, struct wined3d_sampler **sampler); + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler); ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler); void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler); ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler); +HRESULT __cdecl wined3d_shader_create_cs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader); +HRESULT __cdecl wined3d_shader_create_ds(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader); HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, + const struct wined3d_stream_output_desc *so_desc, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader **shader); +HRESULT __cdecl wined3d_shader_create_hs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader); HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader); @@ -2383,8 +2638,9 @@ ULONG __cdecl wined3d_shader_incref(struct wined3d_shader *shader); HRESULT __cdecl wined3d_shader_set_local_constants_float(struct wined3d_shader *shader, UINT start_idx, const float *src_data, UINT vector4f_count); -HRESULT __cdecl wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent, - const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view); +HRESULT __cdecl wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_shader_resource_view **view); ULONG __cdecl wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view); void * __cdecl wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view); ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view); @@ -2415,11 +2671,14 @@ HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapcha struct wined3d_raster_status *raster_status); ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain); HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, - const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, - const RGNDATA *dirty_region, DWORD flags); + const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags); HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality); +HRESULT __cdecl wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, + const struct wined3d_display_mode *mode); +HRESULT __cdecl wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, + const struct wined3d_swapchain_desc *desc, const struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain, DWORD flags, const struct wined3d_gamma_ramp *ramp); void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette); @@ -2431,8 +2690,9 @@ HRESULT __cdecl wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigne struct wined3d_texture *src_texture, unsigned int src_idx, const RECT *src_rect_in, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter); HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, - const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); + UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); +struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture); enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture); @@ -2445,11 +2705,10 @@ void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture) void __cdecl wined3d_texture_get_pitch(const struct wined3d_texture *texture, unsigned int level, unsigned int *row_pitch, unsigned int *slice_pitch); struct wined3d_resource * __cdecl wined3d_texture_get_resource(struct wined3d_texture *texture); -struct wined3d_resource * __cdecl wined3d_texture_get_sub_resource(const struct wined3d_texture *texture, - UINT sub_resource_idx); +HRESULT __cdecl wined3d_texture_get_sub_resource_desc(const struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc); void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx); ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); -void __cdecl wined3d_texture_preload(struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc); HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture, enum wined3d_texture_filter_type filter_type); @@ -2458,6 +2717,8 @@ HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture, DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod); HRESULT __cdecl wined3d_texture_set_overlay_position(struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG x, LONG y); +void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, + unsigned int sub_resource_idx, void *parent); HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality, @@ -2466,6 +2727,13 @@ HRESULT __cdecl wined3d_texture_update_overlay(struct wined3d_texture *texture, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags); +HRESULT __cdecl wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view); +ULONG __cdecl wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view); +void * __cdecl wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view *view); +ULONG __cdecl wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view *view); + HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device, const struct wined3d_vertex_element *elements, UINT element_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_vertex_declaration **declaration); @@ -2507,6 +2775,17 @@ static inline unsigned int wined3d_log2i(unsigned int x) #endif } +static inline void wined3d_box_set(struct wined3d_box *box, unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, unsigned int front, unsigned int back) +{ + box->left = left; + box->top = top; + box->right = right; + box->bottom = bottom; + box->front = front; + box->back = back; +} + BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, enum wined3d_format_id format, unsigned int w, unsigned int h); BOOL wined3d_dxt1_encode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,