Changeset 28475 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
- Timestamp:
- Apr 19, 2010 3:27:01 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
r25949 r28475 189 189 /* We need to deal with frequency data! */ 190 190 IWineD3DVertexDeclarationImpl *declaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl; 191 UINT stream_count = This->stateBlock->streamIsUP ? 0 : declaration->num_streams;192 const DWORD *streams = declaration->streams;193 191 unsigned int i; 194 192 … … 225 223 { 226 224 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); 228 226 229 227 /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets … … 308 306 stream_info->elements[idx].buffer_object = buffer_object; 309 307 310 if (!This->adapter->gl_info.supported[ EXT_VERTEX_ARRAY_BGRA]308 if (!This->adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA] 311 309 && element->format_desc->format == WINED3DFMT_B8G8R8A8_UNORM) 312 310 { … … 317 315 } 318 316 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 } 330 348 } 331 349 } … … 334 352 const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e) 335 353 { 336 const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(strided->format, gl_info);354 const struct wined3d_format_desc *format_desc = getFormatDescEntry(strided->format, gl_info); 337 355 e->format_desc = format_desc; 338 356 e->stride = strided->dwStride; … … 342 360 } 343 361 344 void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,362 static void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info, 345 363 const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info) 346 364 { … … 371 389 if (!stream_info->elements[i].format_desc) continue; 372 390 373 if (!gl_info->supported[ EXT_VERTEX_ARRAY_BGRA]391 if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] 374 392 && stream_info->elements[i].format_desc->format == WINED3DFMT_B8G8R8A8_UNORM) 375 393 { … … 379 397 } 380 398 } 399 400 static 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. */ 421 void 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 470 static 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 480 void 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 514 BOOL 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 534 void 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 381 575 382 576 /********************************************************** … … 426 620 ** ***************************/ 427 621 428 if (!list_empty(&This->resources)) { 622 if (!list_empty(&This->resources)) 623 { 624 IWineD3DResourceImpl *resource; 429 625 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 } 431 633 } 432 634 … … 606 808 HRESULT hr; 607 809 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); 609 815 610 816 if (Impl == SURFACE_OPENGL && !This->adapter) … … 642 848 struct wined3d_rendertarget_view *object; 643 849 850 TRACE("iface %p, resource %p, parent %p, rendertarget_view %p.\n", 851 iface, resource, parent, rendertarget_view); 852 644 853 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 645 854 if (!object) … … 649 858 } 650 859 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); 657 863 *rendertarget_view = (IWineD3DRendertargetView *)object; 658 864 … … 794 1000 } 795 1001 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) { 1002 static 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); 845 1023 return hr; 846 1024 } 847 1025 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 894 1029 return WINED3D_OK; 895 1030 } … … 983 1118 } 984 1119 1120 struct wined3d_fvf_convert_state 1121 { 1122 const struct wined3d_gl_info *gl_info; 1123 WINED3DVERTEXELEMENT *elements; 1124 UINT offset; 1125 UINT idx; 1126 }; 1127 1128 static 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 985 1149 static 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; 990 1153 BOOL has_pos = (fvf & WINED3DFVF_POSITION_MASK) != 0; 991 1154 BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW; … … 1001 1164 DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; 1002 1165 DWORD texcoords = (fvf & 0xFFFF0000) >> 16; 1003 WINED3DVERTEXELEMENT *elements = NULL; 1004 1166 struct wined3d_fvf_convert_state state; 1005 1167 unsigned int size; 1168 unsigned int idx; 1006 1169 DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1); 1007 1170 if (has_blend_idx) num_blends--; … … 1011 1174 has_psize + has_diffuse + has_specular + num_textures; 1012 1175 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; 1043 1212 default: 1044 1213 ERR("Unexpected amount of blend values: %u\n", num_blends); 1045 1214 } 1046 1215 } 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); 1055 1223 else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR) 1056 elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;1224 append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDINDICES, 0); 1057 1225 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 { 1090 1238 case WINED3DFVF_TEXTUREFORMAT1: 1091 elements[idx].format = WINED3DFMT_R32_FLOAT;1239 append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); 1092 1240 break; 1093 1241 case WINED3DFVF_TEXTUREFORMAT2: 1094 elements[idx].format = WINED3DFMT_R32G32_FLOAT;1242 append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); 1095 1243 break; 1096 1244 case WINED3DFVF_TEXTUREFORMAT3: 1097 elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;1245 append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); 1098 1246 break; 1099 1247 case WINED3DFVF_TEXTUREFORMAT4: 1100 elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;1248 append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); 1101 1249 break; 1102 1250 } 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; 1119 1254 return size; 1120 1255 } … … 1235 1370 IWineD3DPaletteImpl *object; 1236 1371 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"); 1243 1380 return E_OUTOFMEMORY; 1244 1381 } 1245 1382 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); 1262 1388 return hr; 1263 1389 } 1264 1390 1265 *Palette = (IWineD3DPalette *) object; 1391 TRACE("Created palette %p.\n", object); 1392 *Palette = (IWineD3DPalette *)object; 1266 1393 1267 1394 return WINED3D_OK; … … 1382 1509 } 1383 1510 1511 static 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 1527 static 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 1384 1535 static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, 1385 1536 WINED3DPRESENT_PARAMETERS *pPresentationParameters) … … 1397 1548 if(This->d3d_initialized) return WINED3DERR_INVALIDCALL; 1398 1549 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 }1410 1550 1411 1551 TRACE("(%p) : Creating stateblock\n", This); … … 1462 1602 } 1463 1603 1464 if (This->focus_window) SetFocus(This->focus_window);1465 1466 1604 /* Setup the implicit swapchain. This also initializes a context. */ 1467 1605 TRACE("Creating implicit swapchain\n"); … … 1534 1672 case ORM_FBO: 1535 1673 This->offscreenBuffer = GL_COLOR_ATTACHMENT0; 1536 break;1537 1538 case ORM_PBUFFER:1539 This->offscreenBuffer = GL_BACK;1540 1674 break; 1541 1675 … … 1598 1732 This->shader_backend->shader_free_private(iface); 1599 1733 } 1600 if (This->focus_window) wined3d_unregister_window(This->focus_window);1601 1734 return hr; 1602 1735 } … … 1672 1805 } 1673 1806 } 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);1685 1807 1686 1808 /* Delete the mouse cursor texture */ … … 1750 1872 1751 1873 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 1755 1876 TRACE("Setting rendertarget to NULL\n"); 1756 1877 This->render_targets[0] = NULL; … … 1788 1909 1789 1910 This->d3d_initialized = FALSE; 1790 1791 if (This->focus_window) wined3d_unregister_window(This->focus_window);1792 1911 1793 1912 return WINED3D_OK; … … 1828 1947 DEVMODEW devmode; 1829 1948 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; 1949 const struct wined3d_format_desc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info); 1830 1950 LONG ret; 1831 const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info);1832 1951 RECT clip_rc; 1833 1952 … … 2943 3062 iface, dstData, start, count); 2944 3063 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) 2946 3065 return WINED3DERR_INVALIDCALL; 2947 3066 … … 3064 3183 } 3065 3184 3066 static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) { 3185 static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info) 3186 { 3067 3187 unsigned int i, tex; 3068 3188 WORD ffu_map; … … 3071 3191 ffu_map = This->fixed_function_usage_map; 3072 3192 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 { 3075 3196 for (i = 0; ffu_map; ffu_map >>= 1, ++i) 3076 3197 { … … 3102 3223 } 3103 3224 3104 static void device_map_psamplers(IWineD3DDeviceImpl *This) { 3225 static void device_map_psamplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info) 3226 { 3105 3227 const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = 3106 3228 ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type; … … 3112 3234 device_map_stage(This, i, i); 3113 3235 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i)); 3114 if (i < MAX_TEXTURES) { 3236 if (i < gl_info->limits.texture_stages) 3237 { 3115 3238 markTextureStagesDirty(This, i); 3116 3239 } … … 3143 3266 } 3144 3267 3145 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { 3268 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct wined3d_gl_info *gl_info) 3269 { 3146 3270 const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type = 3147 3271 ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type; 3148 3272 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; 3150 3274 int i; 3151 3275 … … 3184 3308 } 3185 3309 3186 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) { 3310 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) 3311 { 3312 const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; 3187 3313 BOOL vs = use_vs(This->stateBlock); 3188 3314 BOOL ps = use_ps(This->stateBlock); … … 3194 3320 * to be reset. Because of that try to work with a 1:1 mapping as much as possible 3195 3321 */ 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); 3205 3326 } 3206 3327 … … 3816 3937 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; 3817 3938 DWORD oldValue = This->updateStateBlock->textureState[Stage][Type]; 3939 const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; 3818 3940 3819 3941 TRACE("(%p) : Stage=%d, Type=%s(%d), Value=%d\n", This, Stage, debug_d3dtexturestate(Type), Type, Value); 3820 3942 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); 3823 3947 return WINED3D_OK; 3824 3948 } … … 3901 4025 { 3902 4026 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; 4027 const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; 3903 4028 IWineD3DBaseTexture *prev; 3904 4029 … … 3959 4084 } 3960 4085 3961 if (!prev && stage < MAX_TEXTURES)4086 if (!prev && stage < gl_info->limits.texture_stages) 3962 4087 { 3963 4088 /* The source arguments for color and alpha ops have different … … 3978 4103 IWineD3DBaseTexture_Release(prev); 3979 4104 3980 if (!texture && stage < MAX_TEXTURES)4105 if (!texture && stage < gl_info->limits.texture_stages) 3981 4106 { 3982 4107 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, WINED3DTSS_COLOROP)); … … 4205 4330 } 4206 4331 4332 static 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 4207 4356 /* 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) { 4357 HRESULT 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; 4211 4364 GLbitfield glMask = 0; 4212 4365 unsigned int i; 4213 4366 WINED3DRECT curRect; 4214 4367 RECT vp_rect; 4215 const WINED3DVIEWPORT *vp = &This->stateBlock->viewport;4216 4368 UINT drawable_width, drawable_height; 4217 4369 IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget; 4218 IWineD3DSwapChainImpl *swapchain = NULL;4219 4370 struct wined3d_context *context; 4220 4371 … … 4228 4379 * checking all this if the dest surface is in the drawable anyway. 4229 4380 */ 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); 4253 4385 } 4254 4386 4255 4387 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 } 4256 4417 4257 4418 target->get_drawable_size(context, &drawable_width, &drawable_height); … … 4260 4421 4261 4422 /* 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)); 4263 4432 glClearStencil(Stencil); 4264 4433 checkGLcall("glClearStencil"); 4265 4434 glMask = glMask | GL_STENCIL_BUFFER_BIT; 4266 glStencilMask(0xFFFFFFFF);4267 } 4268 4269 if (Flags & WINED3DCLEAR_ZBUFFER){4435 } 4436 4437 if (Flags & WINED3DCLEAR_ZBUFFER) 4438 { 4270 4439 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 4271 4443 glDepthMask(GL_TRUE); 4444 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); 4272 4445 glClearDepth(Z); 4273 4446 checkGLcall("glClearDepth"); 4274 4447 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)); 4301 4458 checkGLcall("glClearColor"); 4302 4303 /* Clear ALL colors! */4304 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);4305 4459 glMask = glMask | GL_COLOR_BUFFER_BIT; 4306 4460 } … … 4362 4516 } 4363 4517 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 { 4378 4520 IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); 4379 4521 } … … 4386 4528 LEAVE_GL(); 4387 4529 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. */ 4394 4533 4395 4534 context_release(context); … … 5044 5183 } 5045 5184 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; 5185 static 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; 5063 5200 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); 5087 5211 return WINED3DERR_INVALIDCALL; 5088 5212 } 5089 5213 5090 /* This call loads the opengl surface directly, instead of copying the surface to the5091 * destination's sysmem copy. If surface conversion is needed, use BltFast instead to5092 * 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); 5109 5233 5110 5234 context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); … … 5116 5240 5117 5241 /* 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"); 5154 5252 5155 5253 ENTER_GL(); 5156 5254 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) 5166 5262 { 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) 5176 5272 { 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)); 5191 5275 } 5192 5276 else 5193 5277 { 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 } 5199 5310 5200 5311 LEAVE_GL(); 5201 5312 context_release(context); 5202 5313 5203 IWineD3DSurface_ModifyLocation( pDestinationSurface, SFLAG_INTEXTURE, TRUE);5314 IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INTEXTURE, TRUE); 5204 5315 sampler = This->rev_tex_unit_map[0]; 5205 5316 if (sampler != WINED3D_UNMAPPED_STAGE) … … 5331 5442 } 5332 5443 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 5346 5444 static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, 5347 5445 const WINED3DRECT *rect, const float color[4]) … … 5349 5447 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; 5350 5448 struct wined3d_context *context; 5449 5450 if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL); 5451 IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE); 5351 5452 5352 5453 if (!surface_is_offscreen(surface)) … … 5366 5467 ENTER_GL(); 5367 5468 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); 5369 5470 context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); 5370 5471 } … … 5390 5491 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5391 5492 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)); 5392 5496 5393 5497 glClearColor(color[0], color[1], color[2], color[3]); … … 5396 5500 5397 5501 LEAVE_GL(); 5502 5503 if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ 5504 5398 5505 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_UNORM5406 || destfmt == WINED3DFMT_B8G8R8X8_UNORM5407 || 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 }5507 5506 } 5508 5507 … … 5528 5527 memset(&BltFx, 0, sizeof(BltFx)); 5529 5528 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); 5531 5530 return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL, 5532 5531 WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); … … 5576 5575 memset(&BltFx, 0, sizeof(BltFx)); 5577 5576 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); 5579 5578 hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); 5580 5579 if (FAILED(hr)) … … 5607 5606 5608 5607 static 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; 5614 5613 HRESULT hr; 5615 5614 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); 5621 5620 return hr; 5622 5621 } 5623 5622 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); 5629 5627 return WINED3DERR_INVALIDCALL; 5630 5628 } 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)) 5640 5633 { 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) 5688 5640 { 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); 5704 5699 return WINED3D_OK; 5705 5700 } … … 5719 5714 } 5720 5715 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)5716 void 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) 5723 5718 { 5724 5719 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; 5725 5720 GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ 5726 IWineD3DSwapChain *src_swapchain, *dst_swapchain;5727 5721 const struct wined3d_gl_info *gl_info; 5728 5722 struct wined3d_context *context; 5729 5723 GLenum gl_filter; 5730 5724 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; 5736 5734 5737 5735 switch (filter) { … … 5748 5746 } 5749 5747 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); 5756 5756 else context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); 5757 5757 5758 if (!context->valid) 5759 { 5760 context_release(context); 5761 WARN("Invalid context, skipping blit.\n"); 5762 return; 5763 } 5764 5758 5765 gl_info = context->gl_info; 5759 5766 … … 5763 5770 5764 5771 TRACE("Source surface %p is onscreen\n", src_surface); 5765 /* Make sure the drawable is up to date. In the offscreen case5766 * attach_surface_fbo() implicitly takes care of this. */5767 IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);5768 5772 5769 5773 if(buffer == GL_FRONT) { 5770 5774 RECT windowsize; 5771 5775 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); 5774 5778 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; 5778 5782 } 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; 5781 5785 } 5782 5786 … … 5789 5793 ENTER_GL(); 5790 5794 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); 5792 5796 glReadBuffer(GL_COLOR_ATTACHMENT0); 5793 5797 checkGLcall("glReadBuffer()"); … … 5802 5806 5803 5807 TRACE("Destination surface %p is onscreen\n", dst_surface); 5804 /* Make sure the drawable is up to date. In the offscreen case5805 * attach_surface_fbo() implicitly takes care of this. */5806 IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);5807 5808 5808 5809 if(buffer == GL_FRONT) { 5809 5810 RECT windowsize; 5810 5811 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); 5813 5814 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; 5817 5818 } else { 5818 5819 /* 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; 5821 5822 } 5822 5823 … … 5831 5832 ENTER_GL(); 5832 5833 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); 5834 5835 context_set_draw_buffer(context, GL_COLOR_ATTACHMENT0); 5835 5836 context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE); … … 5838 5839 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); 5839 5840 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()"); 5849 5844 5850 5845 LEAVE_GL(); 5846 5847 if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ 5848 5851 5849 context_release(context); 5852 5850 … … 6014 6012 { 6015 6013 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); 6017 6015 struct wined3d_context *context; 6018 6016 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; 6022 6020 INT height = This->cursorHeight; 6023 6021 INT width = This->cursorWidth; 6024 INT bpp = glDesc->byte_count;6022 INT bpp = format_desc->byte_count; 6025 6023 DWORD sampler; 6026 6024 INT i; … … 6207 6205 while (surface->pow2Height < pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1; 6208 6206 } 6209 surface->glRect.left = 0;6210 surface->glRect.top = 0;6211 surface->glRect.right = surface->pow2Width;6212 surface->glRect.bottom = surface->pow2Height;6213 6207 6214 6208 if (surface->texture_name) … … 6276 6270 } 6277 6271 6278 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { 6272 static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) 6273 { 6279 6274 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; 6280 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;6281 6275 const struct wined3d_gl_info *gl_info; 6282 6276 struct wined3d_context *context; … … 6320 6314 } 6321 6315 6322 HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { 6316 static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) 6317 { 6323 6318 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; 6324 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;6325 6319 struct wined3d_context *context; 6326 6320 HRESULT hr; … … 6336 6330 6337 6331 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))) 6340 6333 { 6341 6334 WARN("Failed to create context.\n"); … … 6480 6473 IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock); 6481 6474 6482 delete_opengl_contexts(iface, (IWineD3DSwapChain *)swapchain);6475 delete_opengl_contexts(iface, swapchain); 6483 6476 6484 6477 if(pPresentationParameters->Windowed) { … … 6532 6525 } 6533 6526 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 { 6538 6530 IWineD3DDevice_SetDisplayMode(iface, 0, &mode); 6539 6531 6540 if(swapchain->win_handle && !pPresentationParameters->Windowed) { 6532 if (!pPresentationParameters->Windowed) 6533 { 6541 6534 if(swapchain->presentParms.Windowed) { 6542 6535 /* switch from windowed to fs */ … … 6545 6538 } else { 6546 6539 /* Fullscreen -> fullscreen mode change */ 6547 MoveWindow(swapchain-> win_handle, 0, 0,6540 MoveWindow(swapchain->device_window, 0, 0, 6548 6541 pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight, 6549 6542 TRUE); 6550 6543 } 6551 } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) { 6544 } 6545 else if (!swapchain->presentParms.Windowed) 6546 { 6552 6547 /* Fullscreen -> windowed switch */ 6553 6548 swapchain_restore_fullscreen_window(swapchain); … … 6606 6601 } 6607 6602 6608 hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *)swapchain);6603 hr = create_primary_opengl_context(iface, swapchain); 6609 6604 IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); 6610 6605 … … 6792 6787 } 6793 6788 return WINED3D_OK; 6789 } 6790 6791 static 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; 6794 6811 } 6795 6812 … … 6942 6959 IWineD3DDeviceImpl_GetFrontBufferData, 6943 6960 /*** object tracking ***/ 6944 IWineD3DDeviceImpl_EnumResources 6961 IWineD3DDeviceImpl_EnumResources, 6962 IWineD3DDeviceImpl_GetSurfaceFromDC, 6963 IWineD3DDeviceImpl_AcquireFocusWindow, 6964 IWineD3DDeviceImpl_ReleaseFocusWindow, 6945 6965 }; 6946 6966 … … 6992 7012 6993 7013 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; 6995 7015 6996 7016 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); 6998 7018 device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; 6999 7019 device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; … … 7001 7021 7002 7022 memset(&ffp_caps, 0, sizeof(ffp_caps)); 7003 fragment_pipeline = select_fragment_implementation(adapter, device_type);7023 fragment_pipeline = adapter->fragment_pipe; 7004 7024 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); 7006 7026 device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; 7007 device->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;7008 7027 7009 7028 hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info, … … 7016 7035 } 7017 7036 7018 device->blitter = select_blit_implementation(adapter, device_type);7037 device->blitter = adapter->blitter; 7019 7038 7020 7039 return WINED3D_OK; … … 7040 7059 } 7041 7060 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 7050 7061 void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) 7051 7062 { … … 7058 7069 void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) 7059 7070 { 7060 IWineD3DS urfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;7071 IWineD3DSwapChainImpl *swapchain = context->swapchain; 7061 7072 /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the 7062 7073 * 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; 7067 7077 } 7068 7078
Note:
See TracChangeset
for help on using the changeset viewer.