VirtualBox

Ignore:
Timestamp:
Apr 19, 2010 3:27:01 PM (15 years ago)
Author:
vboxsync
Message:

crOpenGL: update to wine 1.1.43

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c

    r25949 r28475  
    189189    /* We need to deal with frequency data! */
    190190    IWineD3DVertexDeclarationImpl *declaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
    191     UINT stream_count = This->stateBlock->streamIsUP ? 0 : declaration->num_streams;
    192     const DWORD *streams = declaration->streams;
    193191    unsigned int i;
    194192
     
    225223        {
    226224            TRACE("Stream %u isn't UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]);
    227             data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], 0, &buffer_object);
     225            data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], &buffer_object);
    228226
    229227            /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
     
    308306            stream_info->elements[idx].buffer_object = buffer_object;
    309307
    310             if (!This->adapter->gl_info.supported[EXT_VERTEX_ARRAY_BGRA]
     308            if (!This->adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA]
    311309                    && element->format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
    312310            {
     
    317315    }
    318316
    319     /* Now call PreLoad on all the vertex buffers. In the very rare case
    320      * that the buffers stopps converting PreLoad will dirtify the VDECL again.
    321      * The vertex buffer can now use the strided structure in the device instead of finding its
    322      * own again.
    323      *
    324      * NULL streams won't be recorded in the array, UP streams won't be either. A stream is only
    325      * once in there. */
    326     for (i = 0; i < stream_count; ++i)
    327     {
    328         IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]];
    329         if (vb) IWineD3DBuffer_PreLoad(vb);
     317    This->num_buffer_queries = 0;
     318    if (!This->stateBlock->streamIsUP)
     319    {
     320        WORD map = stream_info->use_map;
     321
     322        /* PreLoad all the vertex buffers. */
     323        for (i = 0; map; map >>= 1, ++i)
     324        {
     325            struct wined3d_stream_info_element *element;
     326            struct wined3d_buffer *buffer;
     327            struct wined3d_event_query *query;
     328
     329            if (!(map & 1)) continue;
     330
     331            element = &stream_info->elements[i];
     332            buffer = (struct wined3d_buffer *)This->stateBlock->streamSource[element->stream_idx];
     333            IWineD3DBuffer_PreLoad((IWineD3DBuffer *)buffer);
     334
     335            /* If PreLoad dropped the buffer object, update the stream info. */
     336            if (buffer->buffer_object != element->buffer_object)
     337            {
     338                element->buffer_object = 0;
     339                element->data = buffer_get_sysmem(buffer) + (ptrdiff_t)element->data;
     340            }
     341
     342            query = ((struct wined3d_buffer *) buffer)->query;
     343            if(query)
     344            {
     345                This->buffer_queries[This->num_buffer_queries++] = query;
     346            }
     347        }
    330348    }
    331349}
     
    334352        const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e)
    335353{
    336     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(strided->format, gl_info);
     354    const struct wined3d_format_desc *format_desc = getFormatDescEntry(strided->format, gl_info);
    337355    e->format_desc = format_desc;
    338356    e->stride = strided->dwStride;
     
    342360}
    343361
    344 void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
     362static void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
    345363        const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info)
    346364{
     
    371389        if (!stream_info->elements[i].format_desc) continue;
    372390
    373         if (!gl_info->supported[EXT_VERTEX_ARRAY_BGRA]
     391        if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
    374392                && stream_info->elements[i].format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
    375393        {
     
    379397    }
    380398}
     399
     400static void device_trace_strided_stream_info(const struct wined3d_stream_info *stream_info)
     401{
     402    TRACE("Strided Data:\n");
     403    TRACE_STRIDED(stream_info, WINED3D_FFP_POSITION);
     404    TRACE_STRIDED(stream_info, WINED3D_FFP_BLENDWEIGHT);
     405    TRACE_STRIDED(stream_info, WINED3D_FFP_BLENDINDICES);
     406    TRACE_STRIDED(stream_info, WINED3D_FFP_NORMAL);
     407    TRACE_STRIDED(stream_info, WINED3D_FFP_PSIZE);
     408    TRACE_STRIDED(stream_info, WINED3D_FFP_DIFFUSE);
     409    TRACE_STRIDED(stream_info, WINED3D_FFP_SPECULAR);
     410    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD0);
     411    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD1);
     412    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD2);
     413    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD3);
     414    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD4);
     415    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD5);
     416    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD6);
     417    TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD7);
     418}
     419
     420/* Context activation is done by the caller. */
     421void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info)
     422{
     423    struct wined3d_stream_info *stream_info = &device->strided_streams;
     424    IWineD3DStateBlockImpl *stateblock = device->stateBlock;
     425    BOOL vs = stateblock->vertexShader && device->vs_selected_mode != SHADER_NONE;
     426    BOOL fixup = FALSE;
     427
     428    if (device->up_strided)
     429    {
     430        /* Note: this is a ddraw fixed-function code path. */
     431        TRACE("=============================== Strided Input ================================\n");
     432        device_stream_info_from_strided(gl_info, device->up_strided, stream_info);
     433        if (TRACE_ON(d3d)) device_trace_strided_stream_info(stream_info);
     434    }
     435    else
     436    {
     437        TRACE("============================= Vertex Declaration =============================\n");
     438        device_stream_info_from_declaration(device, vs, stream_info, &fixup);
     439    }
     440
     441    if (vs && !stream_info->position_transformed)
     442    {
     443        if (((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->half_float_conv_needed && !fixup)
     444        {
     445            TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n");
     446            device->useDrawStridedSlow = TRUE;
     447        }
     448        else
     449        {
     450            device->useDrawStridedSlow = FALSE;
     451        }
     452    }
     453    else
     454    {
     455        WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
     456        slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
     457                & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
     458
     459        if ((stream_info->position_transformed || (stream_info->use_map & slow_mask)) && !fixup)
     460        {
     461            device->useDrawStridedSlow = TRUE;
     462        }
     463        else
     464        {
     465            device->useDrawStridedSlow = FALSE;
     466        }
     467    }
     468}
     469
     470static void device_preload_texture(IWineD3DStateBlockImpl *stateblock, unsigned int idx)
     471{
     472    IWineD3DBaseTextureImpl *texture;
     473    enum WINED3DSRGB srgb;
     474
     475    if (!(texture = (IWineD3DBaseTextureImpl *)stateblock->textures[idx])) return;
     476    srgb = stateblock->samplerState[idx][WINED3DSAMP_SRGBTEXTURE] ? SRGB_SRGB : SRGB_RGB;
     477    texture->baseTexture.internal_preload((IWineD3DBaseTexture *)texture, srgb);
     478}
     479
     480void device_preload_textures(IWineD3DDeviceImpl *device)
     481{
     482    IWineD3DStateBlockImpl *stateblock = device->stateBlock;
     483    unsigned int i;
     484
     485    if (use_vs(stateblock))
     486    {
     487        for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
     488        {
     489            if (((IWineD3DBaseShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.sampler_type[i])
     490                device_preload_texture(stateblock, MAX_FRAGMENT_SAMPLERS + i);
     491        }
     492    }
     493
     494    if (use_ps(stateblock))
     495    {
     496        for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     497        {
     498            if (((IWineD3DBaseShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.sampler_type[i])
     499                device_preload_texture(stateblock, i);
     500        }
     501    }
     502    else
     503    {
     504        WORD ffu_map = device->fixed_function_usage_map;
     505
     506        for (i = 0; ffu_map; ffu_map >>= 1, ++i)
     507        {
     508            if (ffu_map & 1)
     509                device_preload_texture(stateblock, i);
     510        }
     511    }
     512}
     513
     514BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context)
     515{
     516    struct wined3d_context **new_array;
     517
     518    TRACE("Adding context %p.\n", context);
     519
     520    if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
     521    else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, sizeof(*new_array) * (device->numContexts + 1));
     522
     523    if (!new_array)
     524    {
     525        ERR("Failed to grow the context array.\n");
     526        return FALSE;
     527    }
     528
     529    new_array[device->numContexts++] = context;
     530    device->contexts = new_array;
     531    return TRUE;
     532}
     533
     534void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context)
     535{
     536    struct wined3d_context **new_array;
     537    BOOL found = FALSE;
     538    UINT i;
     539
     540    TRACE("Removing context %p.\n", context);
     541
     542    for (i = 0; i < device->numContexts; ++i)
     543    {
     544        if (device->contexts[i] == context)
     545        {
     546            found = TRUE;
     547            break;
     548        }
     549    }
     550
     551    if (!found)
     552    {
     553        ERR("Context %p doesn't exist in context array.\n", context);
     554        return;
     555    }
     556
     557    if (!--device->numContexts)
     558    {
     559        HeapFree(GetProcessHeap(), 0, device->contexts);
     560        device->contexts = NULL;
     561        return;
     562    }
     563
     564    memmove(&device->contexts[i], &device->contexts[i + 1], (device->numContexts - i) * sizeof(*device->contexts));
     565    new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->numContexts * sizeof(*device->contexts));
     566    if (!new_array)
     567    {
     568        ERR("Failed to shrink context array. Oh well.\n");
     569        return;
     570    }
     571
     572    device->contexts = new_array;
     573}
     574
    381575
    382576/**********************************************************
     
    426620        ** ***************************/
    427621
    428         if (!list_empty(&This->resources)) {
     622        if (!list_empty(&This->resources))
     623        {
     624            IWineD3DResourceImpl *resource;
    429625            FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This);
    430             dumpResources(&This->resources);
     626
     627            LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
     628            {
     629                WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
     630                FIXME("Leftover resource %p with type %s (%#x).\n",
     631                        resource, debug_d3dresourcetype(type), type);
     632            }
    431633        }
    432634
     
    606808    HRESULT hr;
    607809
    608     TRACE("(%p) Create surface\n",This);
     810    TRACE("iface %p, width %u, height %u, format %s (%#x), lockable %#x, discard %#x, level %u\n",
     811            iface, Width, Height, debug_d3dformat(Format), Format, Lockable, Discard, Level);
     812    TRACE("surface %p, usage %s (%#x), pool %s (%#x), multisample_type %#x, multisample_quality %u\n",
     813            ppSurface, debug_d3dusage(Usage), Usage, debug_d3dpool(Pool), Pool, MultiSample, MultisampleQuality);
     814    TRACE("surface_type %#x, parent %p, parent_ops %p.\n", Impl, parent, parent_ops);
    609815
    610816    if (Impl == SURFACE_OPENGL && !This->adapter)
     
    642848    struct wined3d_rendertarget_view *object;
    643849
     850    TRACE("iface %p, resource %p, parent %p, rendertarget_view %p.\n",
     851            iface, resource, parent, rendertarget_view);
     852
    644853    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    645854    if (!object)
     
    649858    }
    650859
    651     object->vtbl = &wined3d_rendertarget_view_vtbl;
    652     object->refcount = 1;
    653     IWineD3DResource_AddRef(resource);
    654     object->resource = resource;
    655     object->parent = parent;
    656 
     860    wined3d_rendertarget_view_init(object, resource, parent);
     861
     862    TRACE("Created render target view %p.\n", object);
    657863    *rendertarget_view = (IWineD3DRendertargetView *)object;
    658864
     
    7941000}
    7951001
    796 static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINED3DQUERYTYPE Type, IWineD3DQuery **ppQuery, IUnknown* parent) {
    797     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    798     const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    799     IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */
    800     HRESULT hr = WINED3DERR_NOTAVAILABLE;
    801     const IWineD3DQueryVtbl *vtable;
    802 
    803     /* Just a check to see if we support this type of query */
    804     switch(Type) {
    805     case WINED3DQUERYTYPE_OCCLUSION:
    806         TRACE("(%p) occlusion query\n", This);
    807         if (gl_info->supported[ARB_OCCLUSION_QUERY])
    808             hr = WINED3D_OK;
    809         else
    810             WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY/NV_OCCLUSION_QUERY\n");
    811 
    812         vtable = &IWineD3DOcclusionQuery_Vtbl;
    813         break;
    814 
    815     case WINED3DQUERYTYPE_EVENT:
    816         if (!gl_info->supported[NV_FENCE] && !gl_info->supported[APPLE_FENCE])
    817         {
    818             /* Half-Life 2 needs this query. It does not render the main menu correctly otherwise
    819              * Pretend to support it, faking this query does not do much harm except potentially lowering performance
    820              */
    821             FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
    822         }
    823         vtable = &IWineD3DEventQuery_Vtbl;
    824         hr = WINED3D_OK;
    825         break;
    826 
    827     case WINED3DQUERYTYPE_VCACHE:
    828     case WINED3DQUERYTYPE_RESOURCEMANAGER:
    829     case WINED3DQUERYTYPE_VERTEXSTATS:
    830     case WINED3DQUERYTYPE_TIMESTAMP:
    831     case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
    832     case WINED3DQUERYTYPE_TIMESTAMPFREQ:
    833     case WINED3DQUERYTYPE_PIPELINETIMINGS:
    834     case WINED3DQUERYTYPE_INTERFACETIMINGS:
    835     case WINED3DQUERYTYPE_VERTEXTIMINGS:
    836     case WINED3DQUERYTYPE_PIXELTIMINGS:
    837     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
    838     case WINED3DQUERYTYPE_CACHEUTILIZATION:
    839     default:
    840         /* Use the base Query vtable until we have a special one for each query */
    841         vtable = &IWineD3DQuery_Vtbl;
    842         FIXME("(%p) Unhandled query type %d\n", This, Type);
    843     }
    844     if(NULL == ppQuery || hr != WINED3D_OK) {
     1002static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface,
     1003        WINED3DQUERYTYPE type, IWineD3DQuery **query, IUnknown *parent)
     1004{
     1005    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     1006    IWineD3DQueryImpl *object;
     1007    HRESULT hr;
     1008
     1009    TRACE("iface %p, type %#x, query %p, parent %p.\n", iface, type, query, parent);
     1010
     1011    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     1012    if (!object)
     1013    {
     1014        ERR("Failed to allocate query memory.\n");
     1015        return E_OUTOFMEMORY;
     1016    }
     1017
     1018    hr = query_init(object, This, type, parent);
     1019    if (FAILED(hr))
     1020    {
     1021        WARN("Failed to initialize query, hr %#x.\n", hr);
     1022        HeapFree(GetProcessHeap(), 0, object);
    8451023        return hr;
    8461024    }
    8471025
    848     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    849     if(!object)
    850     {
    851         ERR("Out of memory\n");
    852         *ppQuery = NULL;
    853         return WINED3DERR_OUTOFVIDEOMEMORY;
    854     }
    855 
    856     object->lpVtbl = vtable;
    857     object->type = Type;
    858     object->state = QUERY_CREATED;
    859     object->device = This;
    860     object->parent = parent;
    861     object->ref = 1;
    862 
    863     *ppQuery = (IWineD3DQuery *)object;
    864 
    865     /* allocated the 'extended' data based on the type of query requested */
    866     switch(Type){
    867     case WINED3DQUERYTYPE_OCCLUSION:
    868         object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
    869         ((struct wined3d_occlusion_query *)object->extendedData)->context = NULL;
    870         break;
    871 
    872     case WINED3DQUERYTYPE_EVENT:
    873         object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_event_query));
    874         ((struct wined3d_event_query *)object->extendedData)->context = NULL;
    875         break;
    876 
    877     case WINED3DQUERYTYPE_VCACHE:
    878     case WINED3DQUERYTYPE_RESOURCEMANAGER:
    879     case WINED3DQUERYTYPE_VERTEXSTATS:
    880     case WINED3DQUERYTYPE_TIMESTAMP:
    881     case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
    882     case WINED3DQUERYTYPE_TIMESTAMPFREQ:
    883     case WINED3DQUERYTYPE_PIPELINETIMINGS:
    884     case WINED3DQUERYTYPE_INTERFACETIMINGS:
    885     case WINED3DQUERYTYPE_VERTEXTIMINGS:
    886     case WINED3DQUERYTYPE_PIXELTIMINGS:
    887     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
    888     case WINED3DQUERYTYPE_CACHEUTILIZATION:
    889     default:
    890         object->extendedData = 0;
    891         FIXME("(%p) Unhandled query type %d\n",This , Type);
    892     }
    893     TRACE("(%p) : Created Query %p\n", This, object);
     1026    TRACE("Created query %p.\n", object);
     1027    *query = (IWineD3DQuery *)object;
     1028
    8941029    return WINED3D_OK;
    8951030}
     
    9831118}
    9841119
     1120struct wined3d_fvf_convert_state
     1121{
     1122    const struct wined3d_gl_info *gl_info;
     1123    WINED3DVERTEXELEMENT *elements;
     1124    UINT offset;
     1125    UINT idx;
     1126};
     1127
     1128static void append_decl_element(struct wined3d_fvf_convert_state *state,
     1129        WINED3DFORMAT format, WINED3DDECLUSAGE usage, UINT usage_idx)
     1130{
     1131    WINED3DVERTEXELEMENT *elements = state->elements;
     1132    const struct wined3d_format_desc *format_desc;
     1133    UINT offset = state->offset;
     1134    UINT idx = state->idx;
     1135
     1136    elements[idx].format = format;
     1137    elements[idx].input_slot = 0;
     1138    elements[idx].offset = offset;
     1139    elements[idx].output_slot = 0;
     1140    elements[idx].method = WINED3DDECLMETHOD_DEFAULT;
     1141    elements[idx].usage = usage;
     1142    elements[idx].usage_idx = usage_idx;
     1143
     1144    format_desc = getFormatDescEntry(format, state->gl_info);
     1145    state->offset += format_desc->component_count * format_desc->component_size;
     1146    ++state->idx;
     1147}
     1148
    9851149static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */
    986                                             DWORD fvf, WINED3DVERTEXELEMENT** ppVertexElements) {
    987 
    988     unsigned int idx, idx2;
    989     unsigned int offset;
     1150        DWORD fvf, WINED3DVERTEXELEMENT **ppVertexElements)
     1151{
     1152    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    9901153    BOOL has_pos = (fvf & WINED3DFVF_POSITION_MASK) != 0;
    9911154    BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW;
     
    10011164    DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
    10021165    DWORD texcoords = (fvf & 0xFFFF0000) >> 16;
    1003     WINED3DVERTEXELEMENT *elements = NULL;
    1004 
     1166    struct wined3d_fvf_convert_state state;
    10051167    unsigned int size;
     1168    unsigned int idx;
    10061169    DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1);
    10071170    if (has_blend_idx) num_blends--;
     
    10111174           has_psize + has_diffuse + has_specular + num_textures;
    10121175
    1013     /* convert the declaration */
    1014     elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WINED3DVERTEXELEMENT));
    1015     if (!elements) return ~0U;
    1016 
    1017     idx = 0;
    1018     if (has_pos) {
    1019         if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) {
    1020             elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
    1021             elements[idx].usage = WINED3DDECLUSAGE_POSITIONT;
    1022         }
    1023         else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) {
    1024             elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
    1025             elements[idx].usage = WINED3DDECLUSAGE_POSITION;
    1026         }
    1027         else {
    1028             elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
    1029             elements[idx].usage = WINED3DDECLUSAGE_POSITION;
    1030         }
    1031         elements[idx].usage_idx = 0;
    1032         idx++;
    1033     }
    1034     if (has_blend && (num_blends > 0)) {
    1035         if (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))
    1036             elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
    1037         else {
    1038             switch(num_blends) {
    1039                 case 1: elements[idx].format = WINED3DFMT_R32_FLOAT; break;
    1040                 case 2: elements[idx].format = WINED3DFMT_R32G32_FLOAT; break;
    1041                 case 3: elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; break;
    1042                 case 4: elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
     1176    state.gl_info = gl_info;
     1177    state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements));
     1178    if (!state.elements) return ~0U;
     1179    state.offset = 0;
     1180    state.idx = 0;
     1181
     1182    if (has_pos)
     1183    {
     1184        if (!has_blend && (fvf & WINED3DFVF_XYZRHW))
     1185            append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITIONT, 0);
     1186        else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW)
     1187            append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITION, 0);
     1188        else
     1189            append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_POSITION, 0);
     1190    }
     1191
     1192    if (has_blend && (num_blends > 0))
     1193    {
     1194        if ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))
     1195            append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
     1196        else
     1197        {
     1198            switch (num_blends)
     1199            {
     1200                case 1:
     1201                    append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
     1202                    break;
     1203                case 2:
     1204                    append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
     1205                    break;
     1206                case 3:
     1207                    append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
     1208                    break;
     1209                case 4:
     1210                    append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
     1211                    break;
    10431212                default:
    10441213                    ERR("Unexpected amount of blend values: %u\n", num_blends);
    10451214            }
    10461215        }
    1047         elements[idx].usage = WINED3DDECLUSAGE_BLENDWEIGHT;
    1048         elements[idx].usage_idx = 0;
    1049         idx++;
    1050     }
    1051     if (has_blend_idx) {
    1052         if (fvf & WINED3DFVF_LASTBETA_UBYTE4 ||
    1053             (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)))
    1054             elements[idx].format = WINED3DFMT_R8G8B8A8_UINT;
     1216    }
     1217
     1218    if (has_blend_idx)
     1219    {
     1220        if ((fvf & WINED3DFVF_LASTBETA_UBYTE4)
     1221                || ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)))
     1222            append_decl_element(&state, WINED3DFMT_R8G8B8A8_UINT, WINED3DDECLUSAGE_BLENDINDICES, 0);
    10551223        else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)
    1056             elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
     1224            append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDINDICES, 0);
    10571225        else
    1058             elements[idx].format = WINED3DFMT_R32_FLOAT;
    1059         elements[idx].usage = WINED3DDECLUSAGE_BLENDINDICES;
    1060         elements[idx].usage_idx = 0;
    1061         idx++;
    1062     }
    1063     if (has_normal) {
    1064         elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
    1065         elements[idx].usage = WINED3DDECLUSAGE_NORMAL;
    1066         elements[idx].usage_idx = 0;
    1067         idx++;
    1068     }
    1069     if (has_psize) {
    1070         elements[idx].format = WINED3DFMT_R32_FLOAT;
    1071         elements[idx].usage = WINED3DDECLUSAGE_PSIZE;
    1072         elements[idx].usage_idx = 0;
    1073         idx++;
    1074     }
    1075     if (has_diffuse) {
    1076         elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
    1077         elements[idx].usage = WINED3DDECLUSAGE_COLOR;
    1078         elements[idx].usage_idx = 0;
    1079         idx++;
    1080     }
    1081     if (has_specular) {
    1082         elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
    1083         elements[idx].usage = WINED3DDECLUSAGE_COLOR;
    1084         elements[idx].usage_idx = 1;
    1085         idx++;
    1086     }
    1087     for (idx2 = 0; idx2 < num_textures; idx2++) {
    1088         unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03;
    1089         switch (numcoords) {
     1226            append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDINDICES, 0);
     1227    }
     1228
     1229    if (has_normal) append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_NORMAL, 0);
     1230    if (has_psize) append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_PSIZE, 0);
     1231    if (has_diffuse) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 0);
     1232    if (has_specular) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 1);
     1233
     1234    for (idx = 0; idx < num_textures; ++idx)
     1235    {
     1236        switch ((texcoords >> (idx * 2)) & 0x03)
     1237        {
    10901238            case WINED3DFVF_TEXTUREFORMAT1:
    1091                 elements[idx].format = WINED3DFMT_R32_FLOAT;
     1239                append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
    10921240                break;
    10931241            case WINED3DFVF_TEXTUREFORMAT2:
    1094                 elements[idx].format = WINED3DFMT_R32G32_FLOAT;
     1242                append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
    10951243                break;
    10961244            case WINED3DFVF_TEXTUREFORMAT3:
    1097                 elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
     1245                append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
    10981246                break;
    10991247            case WINED3DFVF_TEXTUREFORMAT4:
    1100                 elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
     1248                append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
    11011249                break;
    11021250        }
    1103         elements[idx].usage = WINED3DDECLUSAGE_TEXCOORD;
    1104         elements[idx].usage_idx = idx2;
    1105         idx++;
    1106     }
    1107 
    1108     /* Now compute offsets, and initialize the rest of the fields */
    1109     for (idx = 0, offset = 0; idx < size; ++idx)
    1110     {
    1111         const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(elements[idx].format, &This->adapter->gl_info);
    1112         elements[idx].input_slot = 0;
    1113         elements[idx].method = WINED3DDECLMETHOD_DEFAULT;
    1114         elements[idx].offset = offset;
    1115         offset += format_desc->component_count * format_desc->component_size;
    1116     }
    1117 
    1118     *ppVertexElements = elements;
     1251    }
     1252
     1253    *ppVertexElements = state.elements;
    11191254    return size;
    11201255}
     
    12351370    IWineD3DPaletteImpl *object;
    12361371    HRESULT hr;
    1237     TRACE("(%p)->(%x, %p, %p, %p)\n", This, Flags, PalEnt, Palette, Parent);
    1238 
    1239     /* Create the new object */
    1240     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DPaletteImpl));
    1241     if(!object) {
    1242         ERR("Out of memory when allocating memory for a IWineD3DPalette implementation\n");
     1372
     1373    TRACE("iface %p, flags %#x, entries %p, palette %p, parent %p.\n",
     1374            iface, Flags, PalEnt, Palette, Parent);
     1375
     1376    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     1377    if (!object)
     1378    {
     1379        ERR("Failed to allocate palette memory.\n");
    12431380        return E_OUTOFMEMORY;
    12441381    }
    12451382
    1246     object->lpVtbl = &IWineD3DPalette_Vtbl;
    1247     object->ref = 1;
    1248     object->Flags = Flags;
    1249     object->parent = Parent;
    1250     object->device = This;
    1251     object->palNumEntries = IWineD3DPaletteImpl_Size(Flags);
    1252     object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion));
    1253 
    1254     if(!object->hpal) {
    1255         HeapFree( GetProcessHeap(), 0, object);
    1256         return E_OUTOFMEMORY;
    1257     }
    1258 
    1259     hr = IWineD3DPalette_SetEntries((IWineD3DPalette *) object, 0, 0, IWineD3DPaletteImpl_Size(Flags), PalEnt);
    1260     if(FAILED(hr)) {
    1261         IWineD3DPalette_Release((IWineD3DPalette *) object);
     1383    hr = wined3d_palette_init(object, This, Flags, PalEnt, Parent);
     1384    if (FAILED(hr))
     1385    {
     1386        WARN("Failed to initialize palette, hr %#x.\n", hr);
     1387        HeapFree(GetProcessHeap(), 0, object);
    12621388        return hr;
    12631389    }
    12641390
    1265     *Palette = (IWineD3DPalette *) object;
     1391    TRACE("Created palette %p.\n", object);
     1392    *Palette = (IWineD3DPalette *)object;
    12661393
    12671394    return WINED3D_OK;
     
    13821509}
    13831510
     1511static HRESULT WINAPI IWineD3DDeviceImpl_AcquireFocusWindow(IWineD3DDevice *iface, HWND window)
     1512{
     1513    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
     1514
     1515    if (!wined3d_register_window(window, device))
     1516    {
     1517        ERR("Failed to register window %p.\n", window);
     1518        return E_FAIL;
     1519    }
     1520
     1521    device->focus_window = window;
     1522    SetForegroundWindow(window);
     1523
     1524    return WINED3D_OK;
     1525}
     1526
     1527static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow(IWineD3DDevice *iface)
     1528{
     1529    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
     1530
     1531    if (device->focus_window) wined3d_unregister_window(device->focus_window);
     1532    device->focus_window = NULL;
     1533}
     1534
    13841535static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
    13851536        WINED3DPRESENT_PARAMETERS *pPresentationParameters)
     
    13971548    if(This->d3d_initialized) return WINED3DERR_INVALIDCALL;
    13981549    if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL;
    1399 
    1400     if (!pPresentationParameters->Windowed)
    1401     {
    1402         This->focus_window = This->createParms.hFocusWindow;
    1403         if (!This->focus_window) This->focus_window = pPresentationParameters->hDeviceWindow;
    1404         if (!wined3d_register_window(This->focus_window, This))
    1405         {
    1406             ERR("Failed to register window %p.\n", This->focus_window);
    1407             return E_FAIL;
    1408         }
    1409     }
    14101550
    14111551    TRACE("(%p) : Creating stateblock\n", This);
     
    14621602    }
    14631603
    1464     if (This->focus_window) SetFocus(This->focus_window);
    1465 
    14661604    /* Setup the implicit swapchain. This also initializes a context. */
    14671605    TRACE("Creating implicit swapchain\n");
     
    15341672        case ORM_FBO:
    15351673            This->offscreenBuffer = GL_COLOR_ATTACHMENT0;
    1536             break;
    1537 
    1538         case ORM_PBUFFER:
    1539             This->offscreenBuffer = GL_BACK;
    15401674            break;
    15411675
     
    15981732        This->shader_backend->shader_free_private(iface);
    15991733    }
    1600     if (This->focus_window) wined3d_unregister_window(This->focus_window);
    16011734    return hr;
    16021735}
     
    16721805        }
    16731806    }
    1674 
    1675     /* Delete the palette conversion shader if it is around */
    1676     if(This->paletteConversionShader) {
    1677         ENTER_GL();
    1678         GL_EXTCALL(glDeleteProgramsARB(1, &This->paletteConversionShader));
    1679         LEAVE_GL();
    1680         This->paletteConversionShader = 0;
    1681     }
    1682 
    1683     /* Delete the pbuffer context if there is any */
    1684     if(This->pbufferContext) context_destroy(This, This->pbufferContext);
    16851807
    16861808    /* Delete the mouse cursor texture */
     
    17501872
    17511873    TRACE("Releasing the render target at %p\n", This->render_targets[0]);
    1752     if(IWineD3DSurface_Release(This->render_targets[0]) >0){
    1753           /* This check is a bit silly, it should be in swapchain_release FIXME("(%p) Something's still holding the renderTarget\n",This); */
    1754     }
     1874    IWineD3DSurface_Release(This->render_targets[0]);
     1875
    17551876    TRACE("Setting rendertarget to NULL\n");
    17561877    This->render_targets[0] = NULL;
     
    17881909
    17891910    This->d3d_initialized = FALSE;
    1790 
    1791     if (This->focus_window) wined3d_unregister_window(This->focus_window);
    17921911
    17931912    return WINED3D_OK;
     
    18281947    DEVMODEW devmode;
    18291948    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     1949    const struct wined3d_format_desc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info);
    18301950    LONG ret;
    1831     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info);
    18321951    RECT clip_rc;
    18331952
     
    29433062            iface, dstData, start, count);
    29443063
    2945     if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0)
     3064    if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= 0)
    29463065        return WINED3DERR_INVALIDCALL;
    29473066
     
    30643183}
    30653184
    3066 static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
     3185static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info)
     3186{
    30673187    unsigned int i, tex;
    30683188    WORD ffu_map;
     
    30713191    ffu_map = This->fixed_function_usage_map;
    30723192
    3073     if (This->max_ffp_textures == This->max_ffp_texture_stages ||
    3074             This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures) {
     3193    if (This->max_ffp_textures == gl_info->limits.texture_stages
     3194            || This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures)
     3195    {
    30753196        for (i = 0; ffu_map; ffu_map >>= 1, ++i)
    30763197        {
     
    31023223}
    31033224
    3104 static void device_map_psamplers(IWineD3DDeviceImpl *This) {
     3225static void device_map_psamplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info)
     3226{
    31053227    const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type =
    31063228            ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type;
     
    31123234            device_map_stage(This, i, i);
    31133235            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
    3114             if (i < MAX_TEXTURES) {
     3236            if (i < gl_info->limits.texture_stages)
     3237            {
    31153238                markTextureStagesDirty(This, i);
    31163239            }
     
    31433266}
    31443267
    3145 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
     3268static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct wined3d_gl_info *gl_info)
     3269{
    31463270    const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
    31473271            ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
    31483272    const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
    3149     int start = min(MAX_COMBINED_SAMPLERS, This->adapter->gl_info.limits.combined_samplers) - 1;
     3273    int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
    31503274    int i;
    31513275
     
    31843308}
    31853309
    3186 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
     3310void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This)
     3311{
     3312    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    31873313    BOOL vs = use_vs(This->stateBlock);
    31883314    BOOL ps = use_ps(This->stateBlock);
     
    31943320     * to be reset. Because of that try to work with a 1:1 mapping as much as possible
    31953321     */
    3196     if (ps) {
    3197         device_map_psamplers(This);
    3198     } else {
    3199         device_map_fixed_function_samplers(This);
    3200     }
    3201 
    3202     if (vs) {
    3203         device_map_vsamplers(This, ps);
    3204     }
     3322    if (ps) device_map_psamplers(This, gl_info);
     3323    else device_map_fixed_function_samplers(This, gl_info);
     3324
     3325    if (vs) device_map_vsamplers(This, ps, gl_info);
    32053326}
    32063327
     
    38163937    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    38173938    DWORD oldValue = This->updateStateBlock->textureState[Stage][Type];
     3939    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    38183940
    38193941    TRACE("(%p) : Stage=%d, Type=%s(%d), Value=%d\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
    38203942
    3821     if (Stage >= MAX_TEXTURES) {
    3822         WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring\n", Stage, MAX_TEXTURES - 1);
     3943    if (Stage >= gl_info->limits.texture_stages)
     3944    {
     3945        WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring.\n",
     3946                Stage, gl_info->limits.texture_stages - 1);
    38233947        return WINED3D_OK;
    38243948    }
     
    39014025{
    39024026    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     4027    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    39034028    IWineD3DBaseTexture *prev;
    39044029
     
    39594084        }
    39604085
    3961         if (!prev && stage < MAX_TEXTURES)
     4086        if (!prev && stage < gl_info->limits.texture_stages)
    39624087        {
    39634088            /* The source arguments for color and alpha ops have different
     
    39784103        IWineD3DBaseTexture_Release(prev);
    39794104
    3980         if (!texture && stage < MAX_TEXTURES)
     4105        if (!texture && stage < gl_info->limits.texture_stages)
    39814106        {
    39824107            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, WINED3DTSS_COLOROP));
     
    42054330}
    42064331
     4332static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const WINED3DVIEWPORT *viewport,
     4333        const RECT *scissor_rect, const WINED3DRECT *clear_rect)
     4334{
     4335    /* partial viewport*/
     4336    if (viewport->X != 0 || viewport->Y != 0
     4337            || viewport->Width < target->currentDesc.Width
     4338            || viewport->Height < target->currentDesc.Height)
     4339        return FALSE;
     4340
     4341    /* partial scissor rect */
     4342    if (scissor_rect && (scissor_rect->left > 0 || scissor_rect->top > 0
     4343            || scissor_rect->right < target->currentDesc.Width
     4344            || scissor_rect->bottom < target->currentDesc.Height))
     4345        return FALSE;
     4346
     4347    /* partial clear rect */
     4348    if (clear_rect && (clear_rect->x1 > 0 || clear_rect->y1 > 0
     4349            || clear_rect->x2 < target->currentDesc.Width
     4350            || clear_rect->y2 < target->currentDesc.Height))
     4351        return FALSE;
     4352
     4353    return TRUE;
     4354}
     4355
    42074356/* Not called from the VTable (internal subroutine) */
    4208 HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfaceImpl *target, DWORD Count,
    4209                                         CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
    4210                                         float Z, DWORD Stencil) {
     4357HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
     4358        const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil)
     4359{
     4360    IWineD3DStateBlockImpl *stateblock = This->stateBlock;
     4361    const RECT *scissor_rect = stateblock->renderState[WINED3DRS_SCISSORTESTENABLE] ? &stateblock->scissorRect : NULL;
     4362    const WINED3DRECT *clear_rect = (Count > 0 && pRects) ? pRects : NULL;
     4363    const WINED3DVIEWPORT *vp = &stateblock->viewport;
    42114364    GLbitfield     glMask = 0;
    42124365    unsigned int   i;
    42134366    WINED3DRECT curRect;
    42144367    RECT vp_rect;
    4215     const WINED3DVIEWPORT *vp = &This->stateBlock->viewport;
    42164368    UINT drawable_width, drawable_height;
    42174369    IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
    4218     IWineD3DSwapChainImpl *swapchain = NULL;
    42194370    struct wined3d_context *context;
    42204371
     
    42284379     * checking all this if the dest surface is in the drawable anyway.
    42294380     */
    4230     if((Flags & WINED3DCLEAR_TARGET) && !(target->Flags & SFLAG_INDRAWABLE)) {
    4231         while(1) {
    4232             if(vp->X != 0 || vp->Y != 0 ||
    4233                vp->Width < target->currentDesc.Width || vp->Height < target->currentDesc.Height) {
    4234                 IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
    4235                 break;
    4236             }
    4237             if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
    4238                This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
    4239                This->stateBlock->scissorRect.right < target->currentDesc.Width ||
    4240                This->stateBlock->scissorRect.bottom < target->currentDesc.Height)) {
    4241                 IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
    4242                 break;
    4243             }
    4244             if(Count > 0 && pRects && (
    4245                pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
    4246                pRects[0].x2 < target->currentDesc.Width ||
    4247                pRects[0].y2 < target->currentDesc.Height)) {
    4248                 IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
    4249                 break;
    4250             }
    4251             break;
    4252         }
     4381    if (Flags & WINED3DCLEAR_TARGET && !(target->Flags & SFLAG_INDRAWABLE))
     4382    {
     4383        if (!is_full_clear(target, vp, scissor_rect, clear_rect))
     4384            IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL);
    42534385    }
    42544386
    42554387    context = context_acquire(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR);
     4388    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     4389    {
     4390        if (!surface_is_offscreen((IWineD3DSurface *)target))
     4391        {
     4392            TRACE("Surface %p is onscreen\n", target);
     4393
     4394            ENTER_GL();
     4395            context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
     4396            context_set_draw_buffer(context, surface_get_gl_buffer((IWineD3DSurface *)target));
     4397            LEAVE_GL();
     4398        }
     4399        else
     4400        {
     4401            TRACE("Surface %p is offscreen\n", target);
     4402
     4403            ENTER_GL();
     4404            context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
     4405            context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, target);
     4406            context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, depth_stencil, TRUE);
     4407            LEAVE_GL();
     4408        }
     4409    }
     4410
     4411    if (!context->valid)
     4412    {
     4413        context_release(context);
     4414        WARN("Invalid context, skipping clear.\n");
     4415        return WINED3D_OK;
     4416    }
    42564417
    42574418    target->get_drawable_size(context, &drawable_width, &drawable_height);
     
    42604421
    42614422    /* Only set the values up once, as they are not changing */
    4262     if (Flags & WINED3DCLEAR_STENCIL) {
     4423    if (Flags & WINED3DCLEAR_STENCIL)
     4424    {
     4425        if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE])
     4426        {
     4427            glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
     4428            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE));
     4429        }
     4430        glStencilMask(~0U);
     4431        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK));
    42634432        glClearStencil(Stencil);
    42644433        checkGLcall("glClearStencil");
    42654434        glMask = glMask | GL_STENCIL_BUFFER_BIT;
    4266         glStencilMask(0xFFFFFFFF);
    4267     }
    4268 
    4269     if (Flags & WINED3DCLEAR_ZBUFFER) {
     4435    }
     4436
     4437    if (Flags & WINED3DCLEAR_ZBUFFER)
     4438    {
    42704439        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
     4440        if (!(depth_stencil->Flags & location) && !is_full_clear(depth_stencil, vp, scissor_rect, clear_rect))
     4441            surface_load_ds_location(This->stencilBufferTarget, context, location);
     4442
    42714443        glDepthMask(GL_TRUE);
     4444        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE));
    42724445        glClearDepth(Z);
    42734446        checkGLcall("glClearDepth");
    42744447        glMask = glMask | GL_DEPTH_BUFFER_BIT;
    4275         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE));
    4276 
    4277         if (vp->X != 0 || vp->Y != 0 ||
    4278                 vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) {
    4279             surface_load_ds_location(This->stencilBufferTarget, context, location);
    4280         }
    4281         else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
    4282                 This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
    4283                 This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width ||
    4284                 This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) {
    4285             surface_load_ds_location(This->stencilBufferTarget, context, location);
    4286         }
    4287         else if (Count > 0 && pRects && (
    4288                 pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
    4289                 pRects[0].x2 < depth_stencil->currentDesc.Width ||
    4290                 pRects[0].y2 < depth_stencil->currentDesc.Height)) {
    4291             surface_load_ds_location(This->stencilBufferTarget, context, location);
    4292         }
    4293     }
    4294 
    4295     if (Flags & WINED3DCLEAR_TARGET) {
    4296         TRACE("Clearing screen with glClear to color %x\n", Color);
    4297         glClearColor(D3DCOLOR_R(Color),
    4298                      D3DCOLOR_G(Color),
    4299                      D3DCOLOR_B(Color),
    4300                      D3DCOLOR_A(Color));
     4448    }
     4449
     4450    if (Flags & WINED3DCLEAR_TARGET)
     4451    {
     4452        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     4453        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
     4454        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1));
     4455        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2));
     4456        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3));
     4457        glClearColor(D3DCOLOR_R(Color), D3DCOLOR_G(Color), D3DCOLOR_B(Color), D3DCOLOR_A(Color));
    43014458        checkGLcall("glClearColor");
    4302 
    4303         /* Clear ALL colors! */
    4304         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    43054459        glMask = glMask | GL_COLOR_BUFFER_BIT;
    43064460    }
     
    43624516    }
    43634517
    4364     /* Restore the old values (why..?) */
    4365     if (Flags & WINED3DCLEAR_STENCIL) {
    4366         glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]);
    4367     }
    4368     if (Flags & WINED3DCLEAR_TARGET) {
    4369         DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE];
    4370         glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
    4371                     mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
    4372                     mask & WINED3DCOLORWRITEENABLE_BLUE  ? GL_TRUE : GL_FALSE,
    4373                     mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
    4374 
    4375         /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists,
    4376          * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it
    4377          */
     4518    if (Flags & WINED3DCLEAR_TARGET)
     4519    {
    43784520        IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
    43794521    }
     
    43864528    LEAVE_GL();
    43874529
    4388     if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
    4389         if (target == (IWineD3DSurfaceImpl*) swapchain->frontBuffer) {
    4390             wglFlush();
    4391         }
    4392         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
    4393     }
     4530    if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN)
     4531            && ((IWineD3DSwapChainImpl *)target->container)->frontBuffer == (IWineD3DSurface *)target))
     4532        wglFlush(); /* Flush to ensure ordering across contexts. */
    43944533
    43954534    context_release(context);
     
    50445183}
    50455184
    5046 static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, IWineD3DSurface *pSourceSurface, CONST RECT* pSourceRect, IWineD3DSurface *pDestinationSurface, CONST POINT* pDestPoint) {
    5047     IWineD3DDeviceImpl  *This         = (IWineD3DDeviceImpl *) iface;
    5048     /** TODO: remove casts to IWineD3DSurfaceImpl
    5049      *       NOTE: move code to surface to accomplish this
    5050       ****************************************/
    5051     IWineD3DSurfaceImpl *pSrcSurface  = (IWineD3DSurfaceImpl *)pSourceSurface;
    5052     IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)pDestinationSurface;
    5053     int srcWidth, srcHeight;
    5054     unsigned int  srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight;
    5055     WINED3DFORMAT destFormat, srcFormat;
    5056     UINT          destSize;
    5057     int srcLeft, destLeft, destTop;
    5058     WINED3DPOOL       srcPool, destPool;
    5059     int offset    = 0;
    5060     int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */
    5061     const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc;
    5062     GLenum dummy;
     5185static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
     5186        IWineD3DSurface *src_surface, const RECT *src_rect,
     5187        IWineD3DSurface *dst_surface, const POINT *dst_point)
     5188{
     5189    IWineD3DSurfaceImpl *src_impl = (IWineD3DSurfaceImpl *)src_surface;
     5190    IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)dst_surface;
     5191    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     5192    const struct wined3d_format_desc *src_format;
     5193    const struct wined3d_format_desc *dst_format;
     5194    struct wined3d_context *context;
     5195    const unsigned char *data;
     5196    UINT update_w, update_h;
     5197    CONVERT_TYPES convert;
     5198    UINT src_w, src_h;
     5199    UINT dst_x, dst_y;
    50635200    DWORD sampler;
    5064     int bpp;
    5065     CONVERT_TYPES convert = NO_CONVERSION;
    5066     struct wined3d_context *context;
    5067 
    5068     WINED3DSURFACE_DESC  winedesc;
    5069 
    5070     TRACE("(%p) : Source (%p)  Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
    5071 
    5072     IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
    5073     srcSurfaceWidth = winedesc.width;
    5074     srcSurfaceHeight = winedesc.height;
    5075     srcPool = winedesc.pool;
    5076     srcFormat = winedesc.format;
    5077 
    5078     IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
    5079     destSurfaceWidth = winedesc.width;
    5080     destSurfaceHeight = winedesc.height;
    5081     destPool = winedesc.pool;
    5082     destFormat = winedesc.format;
    5083     destSize = winedesc.size;
    5084 
    5085     if(srcPool != WINED3DPOOL_SYSTEMMEM  || destPool != WINED3DPOOL_DEFAULT){
    5086         WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface);
     5201    struct wined3d_format_desc dummy_desc;
     5202
     5203    TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s",
     5204            iface, src_surface, wine_dbgstr_rect(src_rect),
     5205            dst_surface, wine_dbgstr_point(dst_point));
     5206
     5207    if (src_impl->resource.pool != WINED3DPOOL_SYSTEMMEM || dst_impl->resource.pool != WINED3DPOOL_DEFAULT)
     5208    {
     5209        WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n",
     5210                src_surface, dst_surface);
    50875211        return WINED3DERR_INVALIDCALL;
    50885212    }
    50895213
    5090     /* This call loads the opengl surface directly, instead of copying the surface to the
    5091      * destination's sysmem copy. If surface conversion is needed, use BltFast instead to
    5092      * copy in sysmem and use regular surface loading.
    5093      */
    5094     d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
    5095     if(convert != NO_CONVERSION) {
    5096         return IWineD3DSurface_BltFast(pDestinationSurface,
    5097                                         pDestPoint  ? pDestPoint->x : 0,
    5098                                         pDestPoint  ? pDestPoint->y : 0,
    5099                                         pSourceSurface, pSourceRect, 0);
    5100     }
    5101 
    5102     if (destFormat == WINED3DFMT_UNKNOWN) {
    5103         TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", This);
    5104         IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat);
    5105 
    5106         /* Get the update surface description */
    5107         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
    5108     }
     5214    src_format = src_impl->resource.format_desc;
     5215    dst_format = dst_impl->resource.format_desc;
     5216
     5217    if (src_format->format != dst_format->format)
     5218    {
     5219        WARN("Source and destination surfaces should have the same format.\n");
     5220        return WINED3DERR_INVALIDCALL;
     5221    }
     5222
     5223    dst_x = dst_point ? dst_point->x : 0;
     5224    dst_y = dst_point ? dst_point->y : 0;
     5225
     5226    /* This call loads the OpenGL surface directly, instead of copying the
     5227     * surface to the destination's sysmem copy. If surface conversion is
     5228     * needed, use BltFast instead to copy in sysmem and use regular surface
     5229     * loading. */
     5230    d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy_desc, &convert);
     5231    if (convert != NO_CONVERSION)
     5232        return IWineD3DSurface_BltFast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0);
    51095233
    51105234    context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
     
    51165240
    51175241    /* Make sure the surface is loaded and up to date */
    5118     surface_internal_preload(pDestinationSurface, SRGB_RGB);
    5119     IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
    5120 
    5121     src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc;
    5122     dst_format_desc = dst_impl->resource.format_desc;
    5123 
    5124     /* this needs to be done in lines if the sourceRect != the sourceWidth */
    5125     srcWidth   = pSourceRect ? pSourceRect->right - pSourceRect->left   : srcSurfaceWidth;
    5126     srcHeight  = pSourceRect ? pSourceRect->bottom - pSourceRect->top   : srcSurfaceHeight;
    5127     srcLeft    = pSourceRect ? pSourceRect->left : 0;
    5128     destLeft   = pDestPoint  ? pDestPoint->x : 0;
    5129     destTop    = pDestPoint  ? pDestPoint->y : 0;
    5130 
    5131 
    5132     /* This function doesn't support compressed textures
    5133     the pitch is just bytesPerPixel * width */
    5134     if(srcWidth != srcSurfaceWidth  || srcLeft ){
    5135         rowoffset = srcSurfaceWidth * src_format_desc->byte_count;
    5136         offset   += srcLeft * src_format_desc->byte_count;
    5137         /* TODO: do we ever get 3bpp?, would a shift and an add be quicker than a mul (well maybe a cycle or two) */
    5138     }
    5139     /* TODO DXT formats */
    5140 
    5141     if(pSourceRect != NULL && pSourceRect->top != 0){
    5142        offset +=  pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count;
    5143     }
    5144     TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n",
    5145             This, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
    5146             dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset);
    5147 
    5148     /* Sanity check */
    5149     if (IWineD3DSurface_GetData(pSourceSurface) == NULL) {
    5150 
    5151         /* need to lock the surface to get the data */
    5152         FIXME("Surfaces has no allocated memory, but should be an in memory only surface\n");
    5153     }
     5242    surface_internal_preload(dst_surface, SRGB_RGB);
     5243    IWineD3DSurface_BindTexture(dst_surface, FALSE);
     5244
     5245    src_w = src_impl->currentDesc.Width;
     5246    src_h = src_impl->currentDesc.Height;
     5247    update_w = src_rect ? src_rect->right - src_rect->left : src_w;
     5248    update_h = src_rect ? src_rect->bottom - src_rect->top : src_h;
     5249
     5250    data = IWineD3DSurface_GetData(src_surface);
     5251    if (!data) ERR("Source surface has no allocated memory, but should be a sysmem surface.\n");
    51545252
    51555253    ENTER_GL();
    51565254
    5157     /* TODO: Cube and volume support */
    5158     if(rowoffset != 0){
    5159         /* not a whole row so we have to do it a line at a time */
    5160         int j;
    5161 
    5162         /* hopefully using pointer addition will be quicker than using a point + j * rowoffset */
    5163         const unsigned char* data =((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
    5164 
    5165         for (j = destTop; j < (srcHeight + destTop); ++j)
     5255    if (dst_format->Flags & WINED3DFMT_FLAG_COMPRESSED)
     5256    {
     5257        UINT row_length = (update_w / src_format->block_width) * src_format->block_byte_count;
     5258        UINT row_count = update_h / src_format->block_height;
     5259        UINT src_pitch = IWineD3DSurface_GetPitch(src_surface);
     5260
     5261        if (src_rect)
    51665262        {
    5167             glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j,
    5168                     srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data);
    5169             data += rowoffset;
    5170         }
    5171 
    5172     } else { /* Full width, so just write out the whole texture */
    5173         const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
    5174 
    5175         if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
     5263            data += (src_rect->top / src_format->block_height) * src_pitch;
     5264            data += (src_rect->left / src_format->block_width) * src_format->block_byte_count;
     5265        }
     5266
     5267        TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
     5268                "format %#x, image_size %#x, data %p.\n", dst_impl->texture_target, dst_impl->texture_level,
     5269                dst_x, dst_y, update_w, update_h, dst_format->glFormat, row_count * row_length, data);
     5270
     5271        if (row_length == src_pitch)
    51765272        {
    5177             if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth)
    5178             {
    5179                 /* FIXME: The easy way to do this is to lock the destination, and copy the bits across. */
    5180                 FIXME("Updating part of a compressed texture is not supported.\n");
    5181             }
    5182             if (destFormat != srcFormat)
    5183             {
    5184                 FIXME("Updating mixed format compressed textures is not supported.\n");
    5185             }
    5186             else
    5187             {
    5188                 GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
    5189                         dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
    5190             }
     5273            GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
     5274                    dst_x, dst_y, update_w, update_h, dst_format->glInternal, row_count * row_length, data));
    51915275        }
    51925276        else
    51935277        {
    5194             glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop,
    5195                     srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data);
    5196         }
    5197      }
    5198     checkGLcall("glTexSubImage2D");
     5278            UINT row, y;
     5279
     5280            /* glCompressedTexSubImage2DARB() ignores pixel store state, so we
     5281             * can't use the unpack row length like below. */
     5282            for (row = 0, y = dst_y; row < row_count; ++row)
     5283            {
     5284                GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
     5285                        dst_x, y, update_w, src_format->block_height, dst_format->glInternal, row_length, data));
     5286                y += src_format->block_height;
     5287                data += src_pitch;
     5288            }
     5289        }
     5290        checkGLcall("glCompressedTexSubImage2DARB");
     5291    }
     5292    else
     5293    {
     5294        if (src_rect)
     5295        {
     5296            data += src_rect->top * src_w * src_format->byte_count;
     5297            data += src_rect->left * src_format->byte_count;
     5298        }
     5299
     5300        TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p.\n",
     5301                dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y,
     5302                update_w, update_h, dst_format->glFormat, dst_format->glType, data);
     5303
     5304        glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w);
     5305        glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y,
     5306                update_w, update_h, dst_format->glFormat, dst_format->glType, data);
     5307        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     5308        checkGLcall("glTexSubImage2D");
     5309    }
    51995310
    52005311    LEAVE_GL();
    52015312    context_release(context);
    52025313
    5203     IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE);
     5314    IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INTEXTURE, TRUE);
    52045315    sampler = This->rev_tex_unit_map[0];
    52055316    if (sampler != WINED3D_UNMAPPED_STAGE)
     
    53315442}
    53325443
    5333 static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
    5334     HRESULT hr;
    5335     IWineD3DSwapChain *swapchain;
    5336 
    5337     hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
    5338     if (SUCCEEDED(hr)) {
    5339         IWineD3DSwapChain_Release((IUnknown *)swapchain);
    5340         return swapchain;
    5341     }
    5342 
    5343     return NULL;
    5344 }
    5345 
    53465444static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
    53475445        const WINED3DRECT *rect, const float color[4])
     
    53495447    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
    53505448    struct wined3d_context *context;
     5449
     5450    if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL);
     5451    IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE);
    53515452
    53525453    if (!surface_is_offscreen(surface))
     
    53665467        ENTER_GL();
    53675468        context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
    5368         context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface);
     5469        context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, (IWineD3DSurfaceImpl *)surface);
    53695470        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
    53705471    }
     
    53905491    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    53915492    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
     5493    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1));
     5494    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2));
     5495    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3));
    53925496
    53935497    glClearColor(color[0], color[1], color[2], color[3]);
     
    53965500
    53975501    LEAVE_GL();
     5502
     5503    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
     5504
    53985505    context_release(context);
    5399 }
    5400 
    5401 static inline DWORD argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) {
    5402     unsigned int r, g, b, a;
    5403     DWORD ret;
    5404 
    5405     if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
    5406             || destfmt == WINED3DFMT_B8G8R8X8_UNORM
    5407             || destfmt == WINED3DFMT_B8G8R8_UNORM)
    5408         return color;
    5409 
    5410     TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
    5411 
    5412     a = (color & 0xff000000) >> 24;
    5413     r = (color & 0x00ff0000) >> 16;
    5414     g = (color & 0x0000ff00) >>  8;
    5415     b = (color & 0x000000ff) >>  0;
    5416 
    5417     switch(destfmt)
    5418     {
    5419         case WINED3DFMT_B5G6R5_UNORM:
    5420             if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
    5421             r = (r * 32) / 256;
    5422             g = (g * 64) / 256;
    5423             b = (b * 32) / 256;
    5424             ret  = r << 11;
    5425             ret |= g << 5;
    5426             ret |= b;
    5427             TRACE("Returning %08x\n", ret);
    5428             return ret;
    5429 
    5430         case WINED3DFMT_B5G5R5X1_UNORM:
    5431         case WINED3DFMT_B5G5R5A1_UNORM:
    5432             a = (a *  2) / 256;
    5433             r = (r * 32) / 256;
    5434             g = (g * 32) / 256;
    5435             b = (b * 32) / 256;
    5436             ret  = a << 15;
    5437             ret |= r << 10;
    5438             ret |= g <<  5;
    5439             ret |= b <<  0;
    5440             TRACE("Returning %08x\n", ret);
    5441             return ret;
    5442 
    5443         case WINED3DFMT_A8_UNORM:
    5444             TRACE("Returning %08x\n", a);
    5445             return a;
    5446 
    5447         case WINED3DFMT_B4G4R4X4_UNORM:
    5448         case WINED3DFMT_B4G4R4A4_UNORM:
    5449             a = (a * 16) / 256;
    5450             r = (r * 16) / 256;
    5451             g = (g * 16) / 256;
    5452             b = (b * 16) / 256;
    5453             ret  = a << 12;
    5454             ret |= r <<  8;
    5455             ret |= g <<  4;
    5456             ret |= b <<  0;
    5457             TRACE("Returning %08x\n", ret);
    5458             return ret;
    5459 
    5460         case WINED3DFMT_B2G3R3_UNORM:
    5461             r = (r * 8) / 256;
    5462             g = (g * 8) / 256;
    5463             b = (b * 4) / 256;
    5464             ret  = r <<  5;
    5465             ret |= g <<  2;
    5466             ret |= b <<  0;
    5467             TRACE("Returning %08x\n", ret);
    5468             return ret;
    5469 
    5470         case WINED3DFMT_R8G8B8X8_UNORM:
    5471         case WINED3DFMT_R8G8B8A8_UNORM:
    5472             ret  = a << 24;
    5473             ret |= b << 16;
    5474             ret |= g <<  8;
    5475             ret |= r <<  0;
    5476             TRACE("Returning %08x\n", ret);
    5477             return ret;
    5478 
    5479         case WINED3DFMT_B10G10R10A2_UNORM:
    5480             a = (a *    4) / 256;
    5481             r = (r * 1024) / 256;
    5482             g = (g * 1024) / 256;
    5483             b = (b * 1024) / 256;
    5484             ret  = a << 30;
    5485             ret |= r << 20;
    5486             ret |= g << 10;
    5487             ret |= b <<  0;
    5488             TRACE("Returning %08x\n", ret);
    5489             return ret;
    5490 
    5491         case WINED3DFMT_R10G10B10A2_UNORM:
    5492             a = (a *    4) / 256;
    5493             r = (r * 1024) / 256;
    5494             g = (g * 1024) / 256;
    5495             b = (b * 1024) / 256;
    5496             ret  = a << 30;
    5497             ret |= b << 20;
    5498             ret |= g << 10;
    5499             ret |= r <<  0;
    5500             TRACE("Returning %08x\n", ret);
    5501             return ret;
    5502 
    5503         default:
    5504             FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
    5505             return 0;
    5506     }
    55075506}
    55085507
     
    55285527        memset(&BltFx, 0, sizeof(BltFx));
    55295528        BltFx.dwSize = sizeof(BltFx);
    5530         BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format);
     5529        BltFx.u5.dwFillColor = color_convert_argb_to_fmt(color, surface->resource.format_desc->format);
    55315530        return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
    55325531                WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
     
    55765575        memset(&BltFx, 0, sizeof(BltFx));
    55775576        BltFx.dwSize = sizeof(BltFx);
    5578         BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format);
     5577        BltFx.u5.dwFillColor = color_convert_argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format);
    55795578        hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
    55805579        if (FAILED(hr))
     
    56075606
    56085607static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *iface,
    5609         IWineD3DSurface *Front, IWineD3DSurface *Back)
    5610 {
    5611     IWineD3DSurfaceImpl *FrontImpl = (IWineD3DSurfaceImpl *) Front;
    5612     IWineD3DSurfaceImpl *BackImpl = (IWineD3DSurfaceImpl *) Back;
    5613     IWineD3DSwapChainImpl *Swapchain;
     5608        IWineD3DSurface *front, IWineD3DSurface *back)
     5609{
     5610    IWineD3DSurfaceImpl *front_impl = (IWineD3DSurfaceImpl *)front;
     5611    IWineD3DSurfaceImpl *back_impl = (IWineD3DSurfaceImpl *)back;
     5612    IWineD3DSwapChainImpl *swapchain;
    56145613    HRESULT hr;
    56155614
    5616     TRACE("iface %p, front %p, back %p.\n", iface, Front, Back);
    5617 
    5618     hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &Swapchain);
    5619     if(hr != WINED3D_OK) {
    5620         ERR("Can't get the swapchain\n");
     5615    TRACE("iface %p, front %p, back %p.\n", iface, front, back);
     5616
     5617    if (FAILED(hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&swapchain)))
     5618    {
     5619        ERR("Failed to get the swapchain, hr %#x.\n", hr);
    56215620        return hr;
    56225621    }
    56235622
    5624     /* Make sure to release the swapchain */
    5625     IWineD3DSwapChain_Release((IWineD3DSwapChain *) Swapchain);
    5626 
    5627     if(FrontImpl && !(FrontImpl->resource.usage & WINED3DUSAGE_RENDERTARGET) ) {
    5628         ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n");
     5623    if (front_impl && !(front_impl->resource.usage & WINED3DUSAGE_RENDERTARGET))
     5624    {
     5625        ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n");
     5626        IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
    56295627        return WINED3DERR_INVALIDCALL;
    56305628    }
    5631     else if(BackImpl && !(BackImpl->resource.usage & WINED3DUSAGE_RENDERTARGET)) {
    5632         ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n");
    5633         return WINED3DERR_INVALIDCALL;
    5634     }
    5635 
    5636     if(Swapchain->frontBuffer != Front) {
    5637         TRACE("Changing the front buffer from %p to %p\n", Swapchain->frontBuffer, Front);
    5638 
    5639         if(Swapchain->frontBuffer)
     5629
     5630    if (back_impl)
     5631    {
     5632        if (!(back_impl->resource.usage & WINED3DUSAGE_RENDERTARGET))
    56405633        {
    5641             IWineD3DSurface_SetContainer(Swapchain->frontBuffer, NULL);
    5642             ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN;
    5643         }
    5644         Swapchain->frontBuffer = Front;
    5645 
    5646         if(Swapchain->frontBuffer) {
    5647             IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain);
    5648             ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
    5649         }
    5650     }
    5651 
    5652     if(Back && !Swapchain->backBuffer) {
    5653         /* We need memory for the back buffer array - only one back buffer this way */
    5654         Swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *));
    5655         if(!Swapchain->backBuffer) {
    5656             ERR("Out of memory\n");
    5657             return E_OUTOFMEMORY;
    5658         }
    5659     }
    5660 
    5661     if(Swapchain->backBuffer[0] != Back) {
    5662         TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back);
    5663 
    5664         /* What to do about the context here in the case of multithreading? Not sure.
    5665          * This function is called by IDirect3D7::CreateDevice so in theory its initialization code
    5666          */
    5667         WARN("No active context?\n");
    5668 
    5669         ENTER_GL();
    5670         if(!Swapchain->backBuffer[0]) {
    5671             /* GL was told to draw to the front buffer at creation,
    5672              * undo that
    5673              */
    5674             glDrawBuffer(GL_BACK);
    5675             checkGLcall("glDrawBuffer(GL_BACK)");
    5676             /* Set the backbuffer count to 1 because other code uses it to fing the back buffers */
    5677             Swapchain->presentParms.BackBufferCount = 1;
    5678         } else if (!Back) {
    5679             /* That makes problems - disable for now */
    5680             /* glDrawBuffer(GL_FRONT); */
    5681             checkGLcall("glDrawBuffer(GL_FRONT)");
    5682             /* We have lost our back buffer, set this to 0 to avoid confusing other code */
    5683             Swapchain->presentParms.BackBufferCount = 0;
    5684         }
    5685         LEAVE_GL();
    5686 
    5687         if(Swapchain->backBuffer[0])
     5634            ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n");
     5635            IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
     5636            return WINED3DERR_INVALIDCALL;
     5637        }
     5638
     5639        if (!swapchain->backBuffer)
    56885640        {
    5689             IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL);
    5690             ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN;
    5691         }
    5692         Swapchain->backBuffer[0] = Back;
    5693 
    5694         if(Swapchain->backBuffer[0]) {
    5695             IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain);
    5696             ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN;
    5697         } else {
    5698             HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer);
    5699             Swapchain->backBuffer = NULL;
    5700         }
    5701 
    5702     }
    5703 
     5641            swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->backBuffer));
     5642            if (!swapchain->backBuffer)
     5643            {
     5644                ERR("Failed to allocate back buffer array memory.\n");
     5645                IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
     5646                return E_OUTOFMEMORY;
     5647            }
     5648        }
     5649    }
     5650
     5651    if (swapchain->frontBuffer != front)
     5652    {
     5653        TRACE("Changing the front buffer from %p to %p.\n", swapchain->frontBuffer, front);
     5654
     5655        if (swapchain->frontBuffer)
     5656        {
     5657            IWineD3DSurface_SetContainer(swapchain->frontBuffer, NULL);
     5658            ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN;
     5659        }
     5660        swapchain->frontBuffer = front;
     5661
     5662        if (front)
     5663        {
     5664            IWineD3DSurface_SetContainer(front, (IWineD3DBase *)swapchain);
     5665            front_impl->Flags |= SFLAG_SWAPCHAIN;
     5666        }
     5667    }
     5668
     5669    if (swapchain->backBuffer[0] != back)
     5670    {
     5671        TRACE("Changing the back buffer from %p to %p.\n", swapchain->backBuffer[0], back);
     5672
     5673        if (swapchain->backBuffer[0])
     5674        {
     5675            IWineD3DSurface_SetContainer(swapchain->backBuffer[0], NULL);
     5676            ((IWineD3DSurfaceImpl *)swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN;
     5677        }
     5678        swapchain->backBuffer[0] = back;
     5679
     5680        if (back)
     5681        {
     5682            swapchain->presentParms.BackBufferWidth = back_impl->currentDesc.Width;
     5683            swapchain->presentParms.BackBufferHeight = back_impl->currentDesc.Height;
     5684            swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format;
     5685            swapchain->presentParms.BackBufferCount = 1;
     5686
     5687            IWineD3DSurface_SetContainer(back, (IWineD3DBase *)swapchain);
     5688            back_impl->Flags |= SFLAG_SWAPCHAIN;
     5689        }
     5690        else
     5691        {
     5692            swapchain->presentParms.BackBufferCount = 0;
     5693            HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
     5694            swapchain->backBuffer = NULL;
     5695        }
     5696    }
     5697
     5698    IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
    57045699    return WINED3D_OK;
    57055700}
     
    57195714}
    57205715
    5721 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
    5722         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip)
     5716void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const RECT *src_rect_in,
     5717        IWineD3DSurface *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter)
    57235718{
    57245719    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    57255720    GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
    5726     IWineD3DSwapChain *src_swapchain, *dst_swapchain;
    57275721    const struct wined3d_gl_info *gl_info;
    57285722    struct wined3d_context *context;
    57295723    GLenum gl_filter;
    57305724    POINT offset = {0, 0};
    5731 
    5732     TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n",
    5733             This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip);
    5734     TRACE("src_rect [%u, %u]->[%u, %u]\n", src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2);
    5735     TRACE("dst_rect [%u, %u]->[%u, %u]\n", dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2);
     5725    RECT src_rect, dst_rect;
     5726
     5727    TRACE("(%p) : src_surface %p, src_rect_in %p, dst_surface %p, dst_rect_in %p, filter %s (0x%08x)\n",
     5728            This, src_surface, src_rect_in, dst_surface, dst_rect_in, debug_d3dtexturefiltertype(filter), filter);
     5729    TRACE("src_rect_in %s\n", wine_dbgstr_rect(src_rect_in));
     5730    TRACE("dst_rect_in %s\n", wine_dbgstr_rect(dst_rect_in));
     5731
     5732    src_rect = *src_rect_in;
     5733    dst_rect = *dst_rect_in;
    57365734
    57375735    switch (filter) {
     
    57485746    }
    57495747
    5750     /* Attach src surface to src fbo */
    5751     src_swapchain = get_swapchain(src_surface);
    5752     dst_swapchain = get_swapchain(dst_surface);
    5753 
    5754     if (src_swapchain) context = context_acquire(This, src_surface, CTXUSAGE_RESOURCELOAD);
    5755     else if (dst_swapchain) context = context_acquire(This, dst_surface, CTXUSAGE_RESOURCELOAD);
     5748    /* Make sure the drawables are up-to-date. Note that loading the
     5749     * destination surface isn't strictly required if we overwrite the
     5750     * entire surface. */
     5751    IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
     5752    IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
     5753
     5754    if (!surface_is_offscreen(src_surface)) context = context_acquire(This, src_surface, CTXUSAGE_RESOURCELOAD);
     5755    else if (!surface_is_offscreen(dst_surface)) context = context_acquire(This, dst_surface, CTXUSAGE_RESOURCELOAD);
    57565756    else context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
    57575757
     5758    if (!context->valid)
     5759    {
     5760        context_release(context);
     5761        WARN("Invalid context, skipping blit.\n");
     5762        return;
     5763    }
     5764
    57585765    gl_info = context->gl_info;
    57595766
     
    57635770
    57645771        TRACE("Source surface %p is onscreen\n", src_surface);
    5765         /* Make sure the drawable is up to date. In the offscreen case
    5766          * attach_surface_fbo() implicitly takes care of this. */
    5767         IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
    57685772
    57695773        if(buffer == GL_FRONT) {
    57705774            RECT windowsize;
    57715775            UINT h;
    5772             ClientToScreen(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &offset);
    5773             GetClientRect(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &windowsize);
     5776            ClientToScreen(context->win_handle, &offset);
     5777            GetClientRect(context->win_handle, &windowsize);
    57745778            h = windowsize.bottom - windowsize.top;
    5775             src_rect->x1 -= offset.x; src_rect->x2 -=offset.x;
    5776             src_rect->y1 =  offset.y + h - src_rect->y1;
    5777             src_rect->y2 =  offset.y + h - src_rect->y2;
     5779            src_rect.left -= offset.x; src_rect.right -=offset.x;
     5780            src_rect.top =  offset.y + h - src_rect.top;
     5781            src_rect.bottom =  offset.y + h - src_rect.bottom;
    57785782        } else {
    5779             src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1;
    5780             src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2;
     5783            src_rect.top = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect.top;
     5784            src_rect.bottom = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect.bottom;
    57815785        }
    57825786
     
    57895793        ENTER_GL();
    57905794        context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo);
    5791         context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface);
     5795        context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, (IWineD3DSurfaceImpl *)src_surface);
    57925796        glReadBuffer(GL_COLOR_ATTACHMENT0);
    57935797        checkGLcall("glReadBuffer()");
     
    58025806
    58035807        TRACE("Destination surface %p is onscreen\n", dst_surface);
    5804         /* Make sure the drawable is up to date. In the offscreen case
    5805          * attach_surface_fbo() implicitly takes care of this. */
    5806         IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
    58075808
    58085809        if(buffer == GL_FRONT) {
    58095810            RECT windowsize;
    58105811            UINT h;
    5811             ClientToScreen(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &offset);
    5812             GetClientRect(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &windowsize);
     5812            ClientToScreen(context->win_handle, &offset);
     5813            GetClientRect(context->win_handle, &windowsize);
    58135814            h = windowsize.bottom - windowsize.top;
    5814             dst_rect->x1 -= offset.x; dst_rect->x2 -=offset.x;
    5815             dst_rect->y1 =  offset.y + h - dst_rect->y1;
    5816             dst_rect->y2 =  offset.y + h - dst_rect->y2;
     5815            dst_rect.left -= offset.x; dst_rect.right -=offset.x;
     5816            dst_rect.top =  offset.y + h - dst_rect.top;
     5817            dst_rect.bottom =  offset.y + h - dst_rect.bottom;
    58175818        } else {
    58185819            /* Screen coords = window coords, surface height = window height */
    5819             dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1;
    5820             dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2;
     5820            dst_rect.top = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect.top;
     5821            dst_rect.bottom = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect.bottom;
    58215822        }
    58225823
     
    58315832        ENTER_GL();
    58325833        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo);
    5833         context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface);
     5834        context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, (IWineD3DSurfaceImpl *)dst_surface);
    58345835        context_set_draw_buffer(context, GL_COLOR_ATTACHMENT0);
    58355836        context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE);
     
    58385839    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
    58395840
    5840     if (flip) {
    5841         gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
    5842                 dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter);
    5843         checkGLcall("glBlitFramebuffer()");
    5844     } else {
    5845         gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
    5846                 dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter);
    5847         checkGLcall("glBlitFramebuffer()");
    5848     }
     5841    gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
     5842            dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
     5843    checkGLcall("glBlitFramebuffer()");
    58495844
    58505845    LEAVE_GL();
     5846
     5847    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
     5848
    58515849    context_release(context);
    58525850
     
    60146012            {
    60156013                const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
    6016                 const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
     6014                const struct wined3d_format_desc *format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
    60176015                struct wined3d_context *context;
    60186016                char *mem, *bits = rect.pBits;
    6019                 GLint intfmt = glDesc->glInternal;
    6020                 GLint format = glDesc->glFormat;
    6021                 GLint type = glDesc->glType;
     6017                GLint intfmt = format_desc->glInternal;
     6018                GLint format = format_desc->glFormat;
     6019                GLint type = format_desc->glType;
    60226020                INT height = This->cursorHeight;
    60236021                INT width = This->cursorWidth;
    6024                 INT bpp = glDesc->byte_count;
     6022                INT bpp = format_desc->byte_count;
    60256023                DWORD sampler;
    60266024                INT i;
     
    62076205        while (surface->pow2Height < pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1;
    62086206    }
    6209     surface->glRect.left = 0;
    6210     surface->glRect.top = 0;
    6211     surface->glRect.right = surface->pow2Width;
    6212     surface->glRect.bottom = surface->pow2Height;
    62136207
    62146208    if (surface->texture_name)
     
    62766270}
    62776271
    6278 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
     6272static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain)
     6273{
    62796274    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
    6280     IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
    62816275    const struct wined3d_gl_info *gl_info;
    62826276    struct wined3d_context *context;
     
    63206314}
    63216315
    6322 HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
     6316static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain)
     6317{
    63236318    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
    6324     IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
    63256319    struct wined3d_context *context;
    63266320    HRESULT hr;
     
    63366330
    63376331    target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
    6338     context = context_create(This, target, swapchain->win_handle, FALSE, &swapchain->presentParms);
    6339     if (!context)
     6332    if (!(context = context_create(swapchain, target, swapchain->ds_format)))
    63406333    {
    63416334        WARN("Failed to create context.\n");
     
    64806473    IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
    64816474
    6482     delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain);
     6475    delete_opengl_contexts(iface, swapchain);
    64836476
    64846477    if(pPresentationParameters->Windowed) {
     
    65326525    }
    65336526
    6534     if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) ||
    6535        (swapchain->presentParms.Windowed && !pPresentationParameters->Windowed) ||
    6536         DisplayModeChanged) {
    6537 
     6527    if (!pPresentationParameters->Windowed != !swapchain->presentParms.Windowed
     6528            || DisplayModeChanged)
     6529    {
    65386530        IWineD3DDevice_SetDisplayMode(iface, 0, &mode);
    65396531
    6540         if(swapchain->win_handle && !pPresentationParameters->Windowed) {
     6532        if (!pPresentationParameters->Windowed)
     6533        {
    65416534            if(swapchain->presentParms.Windowed) {
    65426535                /* switch from windowed to fs */
     
    65456538            } else {
    65466539                /* Fullscreen -> fullscreen mode change */
    6547                 MoveWindow(swapchain->win_handle, 0, 0,
     6540                MoveWindow(swapchain->device_window, 0, 0,
    65486541                           pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight,
    65496542                           TRUE);
    65506543            }
    6551         } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) {
     6544        }
     6545        else if (!swapchain->presentParms.Windowed)
     6546        {
    65526547            /* Fullscreen -> windowed switch */
    65536548            swapchain_restore_fullscreen_window(swapchain);
     
    66066601    }
    66076602
    6608     hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain);
     6603    hr = create_primary_opengl_context(iface, swapchain);
    66096604    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
    66106605
     
    67926787    }
    67936788    return WINED3D_OK;
     6789}
     6790
     6791static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface)
     6792{
     6793    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     6794    IWineD3DResourceImpl *resource;
     6795
     6796    LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
     6797    {
     6798        WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
     6799        if (type == WINED3DRTYPE_SURFACE)
     6800        {
     6801            if (((IWineD3DSurfaceImpl *)resource)->hDC == dc)
     6802            {
     6803                TRACE("Found surface %p for dc %p.\n", resource, dc);
     6804                *surface = (IWineD3DSurface *)resource;
     6805                return WINED3D_OK;
     6806            }
     6807        }
     6808    }
     6809
     6810    return WINED3DERR_INVALIDCALL;
    67946811}
    67956812
     
    69426959    IWineD3DDeviceImpl_GetFrontBufferData,
    69436960    /*** object tracking ***/
    6944     IWineD3DDeviceImpl_EnumResources
     6961    IWineD3DDeviceImpl_EnumResources,
     6962    IWineD3DDeviceImpl_GetSurfaceFromDC,
     6963    IWineD3DDeviceImpl_AcquireFocusWindow,
     6964    IWineD3DDeviceImpl_ReleaseFocusWindow,
    69456965};
    69466966
     
    69927012
    69937013    select_shader_mode(&adapter->gl_info, &device->ps_selected_mode, &device->vs_selected_mode);
    6994     device->shader_backend = select_shader_backend(adapter, device_type);
     7014    device->shader_backend = adapter->shader_backend;
    69957015
    69967016    memset(&shader_caps, 0, sizeof(shader_caps));
    6997     device->shader_backend->shader_get_caps(device_type, &adapter->gl_info, &shader_caps);
     7017    device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
    69987018    device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
    69997019    device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
     
    70017021
    70027022    memset(&ffp_caps, 0, sizeof(ffp_caps));
    7003     fragment_pipeline = select_fragment_implementation(adapter, device_type);
     7023    fragment_pipeline = adapter->fragment_pipe;
    70047024    device->frag_pipe = fragment_pipeline;
    7005     fragment_pipeline->get_caps(device_type, &adapter->gl_info, &ffp_caps);
     7025    fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
    70067026    device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
    7007     device->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
    70087027
    70097028    hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info,
     
    70167035    }
    70177036
    7018     device->blitter = select_blit_implementation(adapter, device_type);
     7037    device->blitter = adapter->blitter;
    70197038
    70207039    return WINED3D_OK;
     
    70407059}
    70417060
    7042 void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height)
    7043 {
    7044     IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.device;
    7045     /* The drawable size of a pbuffer render target is the current pbuffer size. */
    7046     *width = device->pbufferWidth;
    7047     *height = device->pbufferHeight;
    7048 }
    7049 
    70507061void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height)
    70517062{
     
    70587069void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height)
    70597070{
    7060     IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;
     7071    IWineD3DSwapChainImpl *swapchain = context->swapchain;
    70617072    /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
    70627073     * current context's drawable, which is the size of the back buffer of the swapchain
    7063      * the active context belongs to. The back buffer of the swapchain is stored as the
    7064      * surface the context belongs to. */
    7065     *width = surface->currentDesc.Width;
    7066     *height = surface->currentDesc.Height;
     7074     * the active context belongs to. */
     7075    *width = swapchain->presentParms.BackBufferWidth;
     7076    *height = swapchain->presentParms.BackBufferHeight;
    70677077}
    70687078
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette