Mercurial > sdl-ios-xcode
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); |