comparison src/render/direct3d/SDL_d3drender.c @ 5159:307ccc9c135e

Made it possible to create a texture of any format, even if not supported by the renderer. This allows me to reduce the set of formats supported by the renderers to the most optimal set, for a nice speed boost.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 03 Feb 2011 00:19:40 -0800
parents fb424691cfc7
children 657543cc92f9
comparison
equal deleted inserted replaced
5158:f3ebd1950442 5159:307ccc9c135e
26 #include "../../core/windows/SDL_windows.h" 26 #include "../../core/windows/SDL_windows.h"
27 27
28 #include "SDL_loadso.h" 28 #include "SDL_loadso.h"
29 #include "SDL_syswm.h" 29 #include "SDL_syswm.h"
30 #include "../SDL_sysrender.h" 30 #include "../SDL_sysrender.h"
31 #include "../../video/SDL_yuv_sw_c.h"
32 31
33 #if SDL_VIDEO_RENDER_D3D 32 #if SDL_VIDEO_RENDER_D3D
34 #define D3D_DEBUG_INFO 33 #define D3D_DEBUG_INFO
35 #include <d3d9.h> 34 #include <d3d9.h>
36 #endif 35 #endif
87 #endif /* ASSEMBLE_SHADER */ 86 #endif /* ASSEMBLE_SHADER */
88 87
89 88
90 /* Direct3D renderer implementation */ 89 /* Direct3D renderer implementation */
91 90
92 #if 1 /* This takes more memory but you won't lose your texture data */ 91 #if 1
92 /* This takes more memory but you won't lose your texture data */
93 #define D3DPOOL_SDL D3DPOOL_MANAGED 93 #define D3DPOOL_SDL D3DPOOL_MANAGED
94 #define SDL_MEMORY_POOL_MANAGED 94 #define SDL_MEMORY_POOL_MANAGED
95 #else 95 #else
96 #define D3DPOOL_SDL D3DPOOL_DEFAULT 96 #define D3DPOOL_SDL D3DPOOL_DEFAULT
97 #define SDL_MEMORY_POOL_DEFAULT 97 #define SDL_MEMORY_POOL_DEFAULT
98 #endif 98 #endif
99 99
100 static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags); 100 static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
101 static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); 101 static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
102 static int D3D_QueryTexturePixels(SDL_Renderer * renderer,
103 SDL_Texture * texture, void **pixels,
104 int *pitch);
105 static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 102 static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
106 const SDL_Rect * rect, const void *pixels, 103 const SDL_Rect * rect, const void *pixels,
107 int pitch); 104 int pitch);
108 static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 105 static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
109 const SDL_Rect * rect, int markDirty, 106 const SDL_Rect * rect, void **pixels, int *pitch);
110 void **pixels, int *pitch);
111 static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 107 static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
112 static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
113 int numrects, const SDL_Rect * rects);
114 static int D3D_RenderDrawPoints(SDL_Renderer * renderer, 108 static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
115 const SDL_Point * points, int count); 109 const SDL_Point * points, int count);
116 static int D3D_RenderDrawLines(SDL_Renderer * renderer, 110 static int D3D_RenderDrawLines(SDL_Renderer * renderer,
117 const SDL_Point * points, int count); 111 const SDL_Point * points, int count);
118 static int D3D_RenderFillRects(SDL_Renderer * renderer, 112 static int D3D_RenderFillRects(SDL_Renderer * renderer,
132 SDL_RenderDriver D3D_RenderDriver = { 126 SDL_RenderDriver D3D_RenderDriver = {
133 D3D_CreateRenderer, 127 D3D_CreateRenderer,
134 { 128 {
135 "d3d", 129 "d3d",
136 (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED), 130 (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
137 0, 131 1,
138 {0}, 132 {SDL_PIXELFORMAT_ARGB8888},
139 0, 133 0,
140 0} 134 0}
141 }; 135 };
142 136
143 typedef struct 137 typedef struct
150 SDL_bool beginScene; 144 SDL_bool beginScene;
151 } D3D_RenderData; 145 } D3D_RenderData;
152 146
153 typedef struct 147 typedef struct
154 { 148 {
155 SDL_SW_YUVTexture *yuv;
156 Uint32 format; 149 Uint32 format;
157 IDirect3DTexture9 *texture; 150 IDirect3DTexture9 *texture;
158 } D3D_TextureData; 151 } D3D_TextureData;
159 152
160 typedef struct 153 typedef struct
246 239
247 static D3DFORMAT 240 static D3DFORMAT
248 PixelFormatToD3DFMT(Uint32 format) 241 PixelFormatToD3DFMT(Uint32 format)
249 { 242 {
250 switch (format) { 243 switch (format) {
251 case SDL_PIXELFORMAT_INDEX8:
252 return D3DFMT_P8;
253 case SDL_PIXELFORMAT_RGB332:
254 return D3DFMT_R3G3B2;
255 case SDL_PIXELFORMAT_RGB444:
256 return D3DFMT_X4R4G4B4;
257 case SDL_PIXELFORMAT_RGB555:
258 return D3DFMT_X1R5G5B5;
259 case SDL_PIXELFORMAT_ARGB4444:
260 return D3DFMT_A4R4G4B4;
261 case SDL_PIXELFORMAT_ARGB1555:
262 return D3DFMT_A1R5G5B5;
263 case SDL_PIXELFORMAT_RGB565: 244 case SDL_PIXELFORMAT_RGB565:
264 return D3DFMT_R5G6B5; 245 return D3DFMT_R5G6B5;
265 case SDL_PIXELFORMAT_RGB888: 246 case SDL_PIXELFORMAT_RGB888:
266 return D3DFMT_X8R8G8B8; 247 return D3DFMT_X8R8G8B8;
267 case SDL_PIXELFORMAT_ARGB8888: 248 case SDL_PIXELFORMAT_ARGB8888:
268 return D3DFMT_A8R8G8B8; 249 return D3DFMT_A8R8G8B8;
269 case SDL_PIXELFORMAT_ARGB2101010:
270 return D3DFMT_A2R10G10B10;
271 case SDL_PIXELFORMAT_YV12:
272 return MAKEFOURCC('Y','V','1','2');
273 case SDL_PIXELFORMAT_IYUV:
274 return MAKEFOURCC('I','4','2','0');
275 case SDL_PIXELFORMAT_UYVY:
276 return D3DFMT_UYVY;
277 case SDL_PIXELFORMAT_YUY2:
278 return D3DFMT_YUY2;
279 default: 250 default:
280 return D3DFMT_UNKNOWN; 251 return D3DFMT_UNKNOWN;
281 } 252 }
282 } 253 }
283 254
284 static SDL_bool 255 static Uint32
285 D3D_IsTextureFormatAvailable(IDirect3D9 * d3d, UINT adapter, 256 D3DFMTToPixelFormat(D3DFORMAT format)
286 D3DFORMAT display_format, 257 {
287 D3DFORMAT texture_format) 258 switch (format) {
288 { 259 case D3DFMT_R5G6B5:
289 HRESULT result; 260 return SDL_PIXELFORMAT_RGB565;
290 261 case D3DFMT_X8R8G8B8:
291 result = IDirect3D9_CheckDeviceFormat(d3d, adapter, 262 return SDL_PIXELFORMAT_RGB888;
292 D3DDEVTYPE_HAL, 263 case D3DFMT_A8R8G8B8:
293 display_format, 264 return SDL_PIXELFORMAT_ARGB8888;
294 0, 265 default:
295 D3DRTYPE_TEXTURE, 266 return SDL_PIXELFORMAT_UNKNOWN;
296 texture_format); 267 }
297 return FAILED(result) ? SDL_FALSE : SDL_TRUE;
298 }
299
300 static void
301 UpdateYUVTextureData(SDL_Texture * texture)
302 {
303 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
304 SDL_Rect rect;
305 RECT d3drect;
306 D3DLOCKED_RECT locked;
307 HRESULT result;
308
309 d3drect.left = 0;
310 d3drect.right = texture->w;
311 d3drect.top = 0;
312 d3drect.bottom = texture->h;
313
314 result =
315 IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
316 if (FAILED(result)) {
317 return;
318 }
319
320 rect.x = 0;
321 rect.y = 0;
322 rect.w = texture->w;
323 rect.h = texture->h;
324 SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
325 texture->h, locked.pBits, locked.Pitch);
326
327 IDirect3DTexture9_UnlockRect(data->texture, 0);
328 }
329
330 static void
331 D3D_AddTextureFormats(D3D_RenderData *data, SDL_RendererInfo *info)
332 {
333 int i;
334 int formats[] = {
335 SDL_PIXELFORMAT_RGB332,
336 SDL_PIXELFORMAT_RGB444,
337 SDL_PIXELFORMAT_RGB555,
338 SDL_PIXELFORMAT_ARGB4444,
339 SDL_PIXELFORMAT_ARGB1555,
340 SDL_PIXELFORMAT_RGB565,
341 SDL_PIXELFORMAT_RGB888,
342 SDL_PIXELFORMAT_ARGB8888,
343 SDL_PIXELFORMAT_ARGB2101010,
344 };
345
346 info->num_texture_formats = 0;
347 for (i = 0; i < SDL_arraysize(formats); ++i) {
348 if (D3D_IsTextureFormatAvailable
349 (data->d3d, data->adapter, data->pparams.BackBufferFormat, PixelFormatToD3DFMT(formats[i]))) {
350 info->texture_formats[info->num_texture_formats++] = formats[i];
351 }
352 }
353 info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YV12;
354 info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
355 info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YUY2;
356 info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
357 info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YVYU;
358 } 268 }
359 269
360 SDL_Renderer * 270 SDL_Renderer *
361 D3D_CreateRenderer(SDL_Window * window, Uint32 flags) 271 D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
362 { 272 {
365 SDL_SysWMinfo windowinfo; 275 SDL_SysWMinfo windowinfo;
366 HRESULT result; 276 HRESULT result;
367 D3DPRESENT_PARAMETERS pparams; 277 D3DPRESENT_PARAMETERS pparams;
368 IDirect3DSwapChain9 *chain; 278 IDirect3DSwapChain9 *chain;
369 D3DCAPS9 caps; 279 D3DCAPS9 caps;
280 Uint32 window_flags;
281 int w, h;
282 SDL_DisplayMode fullscreen_mode;
370 283
371 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); 284 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
372 if (!renderer) { 285 if (!renderer) {
373 SDL_OutOfMemory(); 286 SDL_OutOfMemory();
374 return NULL; 287 return NULL;
402 SDL_SetError("Unable to create Direct3D interface"); 315 SDL_SetError("Unable to create Direct3D interface");
403 return NULL; 316 return NULL;
404 } 317 }
405 318
406 renderer->CreateTexture = D3D_CreateTexture; 319 renderer->CreateTexture = D3D_CreateTexture;
407 renderer->QueryTexturePixels = D3D_QueryTexturePixels;
408 renderer->UpdateTexture = D3D_UpdateTexture; 320 renderer->UpdateTexture = D3D_UpdateTexture;
409 renderer->LockTexture = D3D_LockTexture; 321 renderer->LockTexture = D3D_LockTexture;
410 renderer->UnlockTexture = D3D_UnlockTexture; 322 renderer->UnlockTexture = D3D_UnlockTexture;
411 renderer->DirtyTexture = D3D_DirtyTexture;
412 renderer->RenderDrawPoints = D3D_RenderDrawPoints; 323 renderer->RenderDrawPoints = D3D_RenderDrawPoints;
413 renderer->RenderDrawLines = D3D_RenderDrawLines; 324 renderer->RenderDrawLines = D3D_RenderDrawLines;
414 renderer->RenderFillRects = D3D_RenderFillRects; 325 renderer->RenderFillRects = D3D_RenderFillRects;
415 renderer->RenderCopy = D3D_RenderCopy; 326 renderer->RenderCopy = D3D_RenderCopy;
416 renderer->RenderReadPixels = D3D_RenderReadPixels; 327 renderer->RenderReadPixels = D3D_RenderReadPixels;
425 renderer->info.flags = SDL_RENDERER_ACCELERATED; 336 renderer->info.flags = SDL_RENDERER_ACCELERATED;
426 337
427 SDL_VERSION(&windowinfo.version); 338 SDL_VERSION(&windowinfo.version);
428 SDL_GetWindowWMInfo(window, &windowinfo); 339 SDL_GetWindowWMInfo(window, &windowinfo);
429 340
341 window_flags = SDL_GetWindowFlags(window);
342 SDL_GetWindowSize(window, &w, &h);
343 SDL_GetWindowDisplayMode(window, &fullscreen_mode);
344
430 SDL_zero(pparams); 345 SDL_zero(pparams);
431 pparams.hDeviceWindow = windowinfo.info.win.window; 346 pparams.hDeviceWindow = windowinfo.info.win.window;
432 pparams.BackBufferWidth = window->w; 347 pparams.BackBufferWidth = w;
433 pparams.BackBufferHeight = window->h; 348 pparams.BackBufferHeight = h;
434 if (window->flags & SDL_WINDOW_FULLSCREEN) { 349 if (window_flags & SDL_WINDOW_FULLSCREEN) {
435 pparams.BackBufferFormat = 350 pparams.BackBufferFormat =
436 PixelFormatToD3DFMT(window->fullscreen_mode.format); 351 PixelFormatToD3DFMT(fullscreen_mode.format);
437 } else { 352 } else {
438 pparams.BackBufferFormat = D3DFMT_UNKNOWN; 353 pparams.BackBufferFormat = D3DFMT_UNKNOWN;
439 } 354 }
440 pparams.BackBufferCount = 1; 355 pparams.BackBufferCount = 1;
441 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; 356 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
442 357
443 if (window->flags & SDL_WINDOW_FULLSCREEN) { 358 if (window_flags & SDL_WINDOW_FULLSCREEN) {
444 pparams.Windowed = FALSE; 359 pparams.Windowed = FALSE;
445 pparams.FullScreen_RefreshRateInHz = 360 pparams.FullScreen_RefreshRateInHz =
446 window->fullscreen_mode.refresh_rate; 361 fullscreen_mode.refresh_rate;
447 } else { 362 } else {
448 pparams.Windowed = TRUE; 363 pparams.Windowed = TRUE;
449 pparams.FullScreen_RefreshRateInHz = 0; 364 pparams.FullScreen_RefreshRateInHz = 0;
450 } 365 }
451 if (flags & SDL_RENDERER_PRESENTVSYNC) { 366 if (flags & SDL_RENDERER_PRESENTVSYNC) {
491 IDirect3DSwapChain9_Release(chain); 406 IDirect3DSwapChain9_Release(chain);
492 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { 407 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
493 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; 408 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
494 } 409 }
495 data->pparams = pparams; 410 data->pparams = pparams;
496
497 D3D_AddTextureFormats(data, &renderer->info);
498 411
499 IDirect3DDevice9_GetDeviceCaps(data->device, &caps); 412 IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
500 renderer->info.max_texture_width = caps.MaxTextureWidth; 413 renderer->info.max_texture_width = caps.MaxTextureWidth;
501 renderer->info.max_texture_height = caps.MaxTextureHeight; 414 renderer->info.max_texture_height = caps.MaxTextureHeight;
502 415
592 return -1; 505 return -1;
593 } 506 }
594 507
595 texture->driverdata = data; 508 texture->driverdata = data;
596 509
597 if (SDL_ISPIXELFORMAT_FOURCC(texture->format) && 510 data->format = texture->format;
598 (texture->format != SDL_PIXELFORMAT_YUY2 ||
599 !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter,
600 display_format, PixelFormatToD3DFMT(texture->format)))
601 && (texture->format != SDL_PIXELFORMAT_YVYU
602 || !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter,
603 display_format, PixelFormatToD3DFMT(texture->format)))) {
604 data->yuv =
605 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
606 if (!data->yuv) {
607 return -1;
608 }
609 data->format = SDL_GetWindowPixelFormat(window);
610 } else {
611 data->format = texture->format;
612 }
613 511
614 result = 512 result =
615 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, 513 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
616 texture->h, 1, 0, 514 texture->h, 1, 0,
617 PixelFormatToD3DFMT(data->format), 515 PixelFormatToD3DFMT(data->format),
623 521
624 return 0; 522 return 0;
625 } 523 }
626 524
627 static int 525 static int
628 D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
629 void **pixels, int *pitch)
630 {
631 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
632
633 if (data->yuv) {
634 return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
635 } else {
636 /* D3D textures don't have their pixels hanging out */
637 return -1;
638 }
639 }
640
641 static int
642 D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 526 D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
643 const SDL_Rect * rect, const void *pixels, int pitch) 527 const SDL_Rect * rect, const void *pixels, int pitch)
644 { 528 {
645 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; 529 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
646 D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; 530 D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
647 531
648 if (data->yuv) {
649 if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
650 return -1;
651 }
652 UpdateYUVTextureData(texture);
653 return 0;
654 } else {
655 #ifdef SDL_MEMORY_POOL_DEFAULT 532 #ifdef SDL_MEMORY_POOL_DEFAULT
656 IDirect3DTexture9 *temp; 533 IDirect3DTexture9 *temp;
657 RECT d3drect; 534 RECT d3drect;
658 D3DLOCKED_RECT locked; 535 D3DLOCKED_RECT locked;
659 const Uint8 *src; 536 const Uint8 *src;
660 Uint8 *dst; 537 Uint8 *dst;
661 int row, length; 538 int row, length;
662 HRESULT result; 539 HRESULT result;
663 540
664 result = 541 result =
665 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, 542 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
666 texture->h, 1, 0, 543 texture->h, 1, 0,
667 PixelFormatToD3DFMT(texture-> 544 PixelFormatToD3DFMT(texture-> format),
668 format), 545 D3DPOOL_SYSTEMMEM, &temp, NULL);
669 D3DPOOL_SYSTEMMEM, &temp, NULL); 546 if (FAILED(result)) {
670 if (FAILED(result)) { 547 D3D_SetError("CreateTexture()", result);
671 D3D_SetError("CreateTexture()", result); 548 return -1;
672 return -1; 549 }
673 } 550
674 551 d3drect.left = rect->x;
675 d3drect.left = rect->x; 552 d3drect.right = rect->x + rect->w;
676 d3drect.right = rect->x + rect->w; 553 d3drect.top = rect->y;
677 d3drect.top = rect->y; 554 d3drect.bottom = rect->y + rect->h;
678 d3drect.bottom = rect->y + rect->h; 555
679 556 result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
680 result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0); 557 if (FAILED(result)) {
681 if (FAILED(result)) {
682 IDirect3DTexture9_Release(temp);
683 D3D_SetError("LockRect()", result);
684 return -1;
685 }
686
687 src = pixels;
688 dst = locked.pBits;
689 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
690 for (row = 0; row < rect->h; ++row) {
691 SDL_memcpy(dst, src, length);
692 src += pitch;
693 dst += locked.Pitch;
694 }
695 IDirect3DTexture9_UnlockRect(temp, 0);
696
697 result =
698 IDirect3DDevice9_UpdateTexture(renderdata->device,
699 (IDirect3DBaseTexture9 *) temp,
700 (IDirect3DBaseTexture9 *)
701 data->texture);
702 IDirect3DTexture9_Release(temp); 558 IDirect3DTexture9_Release(temp);
703 if (FAILED(result)) { 559 D3D_SetError("LockRect()", result);
704 D3D_SetError("UpdateTexture()", result); 560 return -1;
705 return -1; 561 }
706 } 562
563 src = pixels;
564 dst = locked.pBits;
565 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
566 for (row = 0; row < rect->h; ++row) {
567 SDL_memcpy(dst, src, length);
568 src += pitch;
569 dst += locked.Pitch;
570 }
571 IDirect3DTexture9_UnlockRect(temp, 0);
572
573 result =
574 IDirect3DDevice9_UpdateTexture(renderdata->device,
575 (IDirect3DBaseTexture9 *) temp,
576 (IDirect3DBaseTexture9 *)
577 data->texture);
578 IDirect3DTexture9_Release(temp);
579 if (FAILED(result)) {
580 D3D_SetError("UpdateTexture()", result);
581 return -1;
582 }
707 #else 583 #else
708 RECT d3drect; 584 RECT d3drect;
709 D3DLOCKED_RECT locked; 585 D3DLOCKED_RECT locked;
710 const Uint8 *src; 586 const Uint8 *src;
711 Uint8 *dst; 587 Uint8 *dst;
712 int row, length; 588 int row, length;
713 HRESULT result; 589 HRESULT result;
714 590
715 d3drect.left = rect->x; 591 d3drect.left = rect->x;
716 d3drect.right = rect->x + rect->w; 592 d3drect.right = rect->x + rect->w;
717 d3drect.top = rect->y; 593 d3drect.top = rect->y;
718 d3drect.bottom = rect->y + rect->h; 594 d3drect.bottom = rect->y + rect->h;
719 595
720 result = 596 result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
721 IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 597 if (FAILED(result)) {
722 0); 598 D3D_SetError("LockRect()", result);
723 if (FAILED(result)) { 599 return -1;
724 D3D_SetError("LockRect()", result); 600 }
725 return -1; 601
726 } 602 src = pixels;
727 603 dst = locked.pBits;
728 src = pixels; 604 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
729 dst = locked.pBits; 605 for (row = 0; row < rect->h; ++row) {
730 length = rect->w * SDL_BYTESPERPIXEL(texture->format); 606 SDL_memcpy(dst, src, length);
731 for (row = 0; row < rect->h; ++row) { 607 src += pitch;
732 SDL_memcpy(dst, src, length); 608 dst += locked.Pitch;
733 src += pitch; 609 }
734 dst += locked.Pitch; 610 IDirect3DTexture9_UnlockRect(data->texture, 0);
735 }
736 IDirect3DTexture9_UnlockRect(data->texture, 0);
737 #endif // SDL_MEMORY_POOL_DEFAULT 611 #endif // SDL_MEMORY_POOL_DEFAULT
738 612
739 return 0; 613 return 0;
740 }
741 } 614 }
742 615
743 static int 616 static int
744 D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 617 D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
745 const SDL_Rect * rect, int markDirty, void **pixels, 618 const SDL_Rect * rect, void **pixels, int *pitch)
746 int *pitch)
747 { 619 {
748 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; 620 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
749 621 RECT d3drect;
750 if (data->yuv) { 622 D3DLOCKED_RECT locked;
751 return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, 623 HRESULT result;
752 pitch); 624
753 } else { 625 d3drect.left = rect->x;
754 RECT d3drect; 626 d3drect.right = rect->x + rect->w;
755 D3DLOCKED_RECT locked; 627 d3drect.top = rect->y;
756 HRESULT result; 628 d3drect.bottom = rect->y + rect->h;
757 629
758 d3drect.left = rect->x; 630 result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
759 d3drect.right = rect->x + rect->w; 631 if (FAILED(result)) {
760 d3drect.top = rect->y; 632 D3D_SetError("LockRect()", result);
761 d3drect.bottom = rect->y + rect->h; 633 return -1;
762 634 }
763 result = 635 *pixels = locked.pBits;
764 IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 636 *pitch = locked.Pitch;
765 markDirty ? 0 : 637 return 0;
766 D3DLOCK_NO_DIRTY_UPDATE);
767 if (FAILED(result)) {
768 D3D_SetError("LockRect()", result);
769 return -1;
770 }
771 *pixels = locked.pBits;
772 *pitch = locked.Pitch;
773 return 0;
774 }
775 } 638 }
776 639
777 static void 640 static void
778 D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) 641 D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
779 { 642 {
780 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; 643 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
781 644
782 if (data->yuv) { 645 IDirect3DTexture9_UnlockRect(data->texture, 0);
783 SDL_SW_UnlockYUVTexture(data->yuv);
784 UpdateYUVTextureData(texture);
785 } else {
786 IDirect3DTexture9_UnlockRect(data->texture, 0);
787 }
788 }
789
790 static void
791 D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
792 const SDL_Rect * rects)
793 {
794 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
795 RECT d3drect;
796 int i;
797
798 for (i = 0; i < numrects; ++i) {
799 const SDL_Rect *rect = &rects[i];
800
801 d3drect.left = rect->x;
802 d3drect.right = rect->x + rect->w;
803 d3drect.top = rect->y;
804 d3drect.bottom = rect->y + rect->h;
805
806 IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
807 }
808 } 646 }
809 647
810 static void 648 static void
811 D3D_SetBlendMode(D3D_RenderData * data, int blendMode) 649 D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
812 { 650 {
1121 static int 959 static int
1122 D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 960 D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1123 Uint32 format, void * pixels, int pitch) 961 Uint32 format, void * pixels, int pitch)
1124 { 962 {
1125 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; 963 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1126 SDL_Window *window = renderer->window;
1127 SDL_VideoDisplay *display = window->display;
1128 D3DSURFACE_DESC desc; 964 D3DSURFACE_DESC desc;
1129 LPDIRECT3DSURFACE9 backBuffer; 965 LPDIRECT3DSURFACE9 backBuffer;
1130 LPDIRECT3DSURFACE9 surface; 966 LPDIRECT3DSURFACE9 surface;
1131 RECT d3drect; 967 RECT d3drect;
1132 D3DLOCKED_RECT locked; 968 D3DLOCKED_RECT locked;
1172 IDirect3DSurface9_Release(backBuffer); 1008 IDirect3DSurface9_Release(backBuffer);
1173 return -1; 1009 return -1;
1174 } 1010 }
1175 1011
1176 SDL_ConvertPixels(rect->w, rect->h, 1012 SDL_ConvertPixels(rect->w, rect->h,
1177 display->current_mode.format, locked.pBits, locked.Pitch, 1013 D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
1178 format, pixels, pitch); 1014 format, pixels, pitch);
1179 1015
1180 IDirect3DSurface9_UnlockRect(surface); 1016 IDirect3DSurface9_UnlockRect(surface);
1181 1017
1182 IDirect3DSurface9_Release(surface); 1018 IDirect3DSurface9_Release(surface);
1224 { 1060 {
1225 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; 1061 D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
1226 1062
1227 if (!data) { 1063 if (!data) {
1228 return; 1064 return;
1229 }
1230 if (data->yuv) {
1231 SDL_SW_DestroyYUVTexture(data->yuv);
1232 } 1065 }
1233 if (data->texture) { 1066 if (data->texture) {
1234 IDirect3DTexture9_Release(data->texture); 1067 IDirect3DTexture9_Release(data->texture);
1235 } 1068 }
1236 SDL_free(data); 1069 SDL_free(data);