~ubuntu-branches/ubuntu/trusty/libsdl2/trusty-proposed

« back to all changes in this revision

Viewing changes to src/render/direct3d/SDL_render_d3d.c

  • Committer: Package Import Robot
  • Author(s): Manuel A. Fernandez Montecelo
  • Date: 2013-12-28 12:31:19 UTC
  • mto: (7.1.3 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: package-import@ubuntu.com-20131228123119-wehupm72qsjvh6vz
Tags: upstream-2.0.1+dfsg1
ImportĀ upstreamĀ versionĀ 2.0.1+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
24
24
 
25
 
 
26
25
#include "../../core/windows/SDL_windows.h"
27
26
 
28
27
#include "SDL_hints.h"
29
28
#include "SDL_loadso.h"
30
29
#include "SDL_syswm.h"
 
30
#include "SDL_system.h"
31
31
#include "../SDL_sysrender.h"
32
 
#include <stdio.h>
 
32
#include "../../video/windows/SDL_windowsvideo.h"
33
33
 
34
34
#if SDL_VIDEO_RENDER_D3D
35
35
#define D3D_DEBUG_INFO
207
207
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
208
208
                             const SDL_Rect * rect, const void *pixels,
209
209
                             int pitch);
 
210
static int D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
 
211
                                const SDL_Rect * rect,
 
212
                                const Uint8 *Yplane, int Ypitch,
 
213
                                const Uint8 *Uplane, int Upitch,
 
214
                                const Uint8 *Vplane, int Vpitch);
210
215
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
211
216
                           const SDL_Rect * rect, void **pixels, int *pitch);
212
217
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
395
400
    }
396
401
}
397
402
 
 
403
static void
 
404
D3D_InitRenderState(D3D_RenderData *data)
 
405
{
 
406
    D3DMATRIX matrix;
 
407
 
 
408
    IDirect3DDevice9 *device = data->device;
 
409
 
 
410
    IDirect3DDevice9_SetVertexShader(device, NULL);
 
411
    IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
 
412
    IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
 
413
    IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
 
414
    IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
 
415
 
 
416
    /* Enable color modulation by diffuse color */
 
417
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP,
 
418
                                          D3DTOP_MODULATE);
 
419
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1,
 
420
                                          D3DTA_TEXTURE);
 
421
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2,
 
422
                                          D3DTA_DIFFUSE);
 
423
 
 
424
    /* Enable alpha modulation by diffuse alpha */
 
425
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP,
 
426
                                          D3DTOP_MODULATE);
 
427
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1,
 
428
                                          D3DTA_TEXTURE);
 
429
    IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG2,
 
430
                                          D3DTA_DIFFUSE);
 
431
 
 
432
    /* Enable separate alpha blend function, if possible */
 
433
    if (data->enableSeparateAlphaBlend) {
 
434
        IDirect3DDevice9_SetRenderState(device, D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
 
435
    }
 
436
 
 
437
    /* Disable second texture stage, since we're done */
 
438
    IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP,
 
439
                                          D3DTOP_DISABLE);
 
440
    IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP,
 
441
                                          D3DTOP_DISABLE);
 
442
 
 
443
    /* Set an identity world and view matrix */
 
444
    matrix.m[0][0] = 1.0f;
 
445
    matrix.m[0][1] = 0.0f;
 
446
    matrix.m[0][2] = 0.0f;
 
447
    matrix.m[0][3] = 0.0f;
 
448
    matrix.m[1][0] = 0.0f;
 
449
    matrix.m[1][1] = 1.0f;
 
450
    matrix.m[1][2] = 0.0f;
 
451
    matrix.m[1][3] = 0.0f;
 
452
    matrix.m[2][0] = 0.0f;
 
453
    matrix.m[2][1] = 0.0f;
 
454
    matrix.m[2][2] = 1.0f;
 
455
    matrix.m[2][3] = 0.0f;
 
456
    matrix.m[3][0] = 0.0f;
 
457
    matrix.m[3][1] = 0.0f;
 
458
    matrix.m[3][2] = 0.0f;
 
459
    matrix.m[3][3] = 1.0f;
 
460
    IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &matrix);
 
461
    IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &matrix);
 
462
 
 
463
    /* Reset our current scale mode */
 
464
    SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
 
465
 
 
466
    /* Start the render with beginScene */
 
467
    data->beginScene = SDL_TRUE;
 
468
}
 
469
 
398
470
static int
399
471
D3D_Reset(SDL_Renderer * renderer)
400
472
{
416
488
            return D3D_SetError("Reset()", result);
417
489
        }
418
490
    }
419
 
    IDirect3DDevice9_SetVertexShader(data->device, NULL);
420
 
    IDirect3DDevice9_SetFVF(data->device,
421
 
                            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
422
 
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
423
 
                                    D3DCULL_NONE);
424
 
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
 
491
 
425
492
    IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
426
 
    SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
 
493
    D3D_InitRenderState(data);
427
494
    D3D_UpdateViewport(renderer);
428
495
    return 0;
429
496
}
476
543
    D3D_RenderData *data;
477
544
    SDL_SysWMinfo windowinfo;
478
545
    HRESULT result;
 
546
    const char *hint;
479
547
    D3DPRESENT_PARAMETERS pparams;
480
548
    IDirect3DSwapChain9 *chain;
481
549
    D3DCAPS9 caps;
 
550
    DWORD device_flags;
482
551
    Uint32 window_flags;
483
552
    int w, h;
484
553
    SDL_DisplayMode fullscreen_mode;
485
 
    D3DMATRIX matrix;
486
554
    int d3dxVersion;
487
555
    char d3dxDLLFile[50];
 
556
    int displayIndex;
488
557
 
489
558
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
490
559
    if (!renderer) {
499
568
        return NULL;
500
569
    }
501
570
 
502
 
    data->d3dDLL = SDL_LoadObject("D3D9.DLL");
503
 
    if (data->d3dDLL) {
504
 
        IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion);
505
 
 
506
 
        D3DCreate =
507
 
            (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL,
508
 
                                                            "Direct3DCreate9");
509
 
        if (D3DCreate) {
510
 
            data->d3d = D3DCreate(D3D_SDK_VERSION);
511
 
        }
512
 
        if (!data->d3d) {
513
 
            SDL_UnloadObject(data->d3dDLL);
514
 
            data->d3dDLL = NULL;
515
 
        }
516
 
 
 
571
    if( D3D_LoadDLL( &data->d3dDLL, &data->d3d ) ) {
517
572
        for (d3dxVersion=50;d3dxVersion>0;d3dxVersion--) {
518
573
            LPTSTR dllName;
519
574
            SDL_snprintf(d3dxDLLFile, sizeof(d3dxDLLFile), "D3DX9_%02d.dll", d3dxVersion);
535
590
        }
536
591
    }
537
592
 
538
 
 
539
 
 
540
593
    if (!data->d3d || !data->matrixStack) {
541
594
        SDL_free(renderer);
542
595
        SDL_free(data);
547
600
    renderer->WindowEvent = D3D_WindowEvent;
548
601
    renderer->CreateTexture = D3D_CreateTexture;
549
602
    renderer->UpdateTexture = D3D_UpdateTexture;
 
603
    renderer->UpdateTextureYUV = D3D_UpdateTextureYUV;
550
604
    renderer->LockTexture = D3D_LockTexture;
551
605
    renderer->UnlockTexture = D3D_UnlockTexture;
552
606
    renderer->SetRenderTarget = D3D_SetRenderTarget;
606
660
        pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
607
661
    }
608
662
 
609
 
    /* FIXME: Which adapter? */
610
 
    data->adapter = D3DADAPTER_DEFAULT;
 
663
    /* Get the adapter for the display that the window is on */
 
664
    displayIndex = SDL_GetWindowDisplayIndex( window );
 
665
    data->adapter = SDL_Direct3D9GetAdapterIndex( displayIndex );
 
666
 
611
667
    IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
612
668
 
 
669
    device_flags = D3DCREATE_FPU_PRESERVE;
 
670
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
 
671
        device_flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
 
672
    } else {
 
673
        device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
 
674
    }
 
675
 
 
676
    hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D_THREADSAFE);
 
677
    if (hint && SDL_atoi(hint)) {
 
678
        device_flags |= D3DCREATE_MULTITHREADED;
 
679
    }
 
680
 
613
681
    result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
614
682
                                     D3DDEVTYPE_HAL,
615
683
                                     pparams.hDeviceWindow,
616
 
                                     D3DCREATE_FPU_PRESERVE | ((caps.
617
 
                                      DevCaps &
618
 
                                      D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
619
 
                                     D3DCREATE_HARDWARE_VERTEXPROCESSING :
620
 
                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING),
 
684
                                     device_flags,
621
685
                                     &pparams, &data->device);
622
686
    if (FAILED(result)) {
623
687
        D3D_DestroyRenderer(renderer);
624
688
        D3D_SetError("CreateDevice()", result);
625
689
        return NULL;
626
690
    }
627
 
    data->beginScene = SDL_TRUE;
628
 
    SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
629
691
 
630
692
    /* Get presentation parameters to fill info */
631
693
    result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
658
720
        data->enableSeparateAlphaBlend = SDL_TRUE;
659
721
    }
660
722
 
661
 
    /* Set up parameters for rendering */
662
 
    IDirect3DDevice9_SetVertexShader(data->device, NULL);
663
 
    IDirect3DDevice9_SetFVF(data->device,
664
 
                            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
665
 
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
666
 
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
667
 
                                    D3DCULL_NONE);
668
 
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
669
 
    /* Enable color modulation by diffuse color */
670
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
671
 
                                          D3DTOP_MODULATE);
672
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
673
 
                                          D3DTA_TEXTURE);
674
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
675
 
                                          D3DTA_DIFFUSE);
676
 
    /* Enable alpha modulation by diffuse alpha */
677
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
678
 
                                          D3DTOP_MODULATE);
679
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
680
 
                                          D3DTA_TEXTURE);
681
 
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
682
 
                                          D3DTA_DIFFUSE);
683
 
    /* Enable separate alpha blend function, if possible */
684
 
    if (data->enableSeparateAlphaBlend) {
685
 
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
686
 
    }
687
 
    /* Disable second texture stage, since we're done */
688
 
    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
689
 
                                          D3DTOP_DISABLE);
690
 
    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
691
 
                                          D3DTOP_DISABLE);
692
 
 
693
723
    /* Store the default render target */
694
724
    IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
695
725
    data->currentRenderTarget = NULL;
696
726
 
697
 
    /* Set an identity world and view matrix */
698
 
    matrix.m[0][0] = 1.0f;
699
 
    matrix.m[0][1] = 0.0f;
700
 
    matrix.m[0][2] = 0.0f;
701
 
    matrix.m[0][3] = 0.0f;
702
 
    matrix.m[1][0] = 0.0f;
703
 
    matrix.m[1][1] = 1.0f;
704
 
    matrix.m[1][2] = 0.0f;
705
 
    matrix.m[1][3] = 0.0f;
706
 
    matrix.m[2][0] = 0.0f;
707
 
    matrix.m[2][1] = 0.0f;
708
 
    matrix.m[2][2] = 1.0f;
709
 
    matrix.m[2][3] = 0.0f;
710
 
    matrix.m[3][0] = 0.0f;
711
 
    matrix.m[3][1] = 0.0f;
712
 
    matrix.m[3][2] = 0.0f;
713
 
    matrix.m[3][3] = 1.0f;
714
 
    IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix);
715
 
    IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix);
 
727
    /* Set up parameters for rendering */
 
728
    D3D_InitRenderState(data);
716
729
 
717
730
    if (caps.MaxSimultaneousTextures >= 3)
718
731
    {
864
877
 
865
878
    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
866
879
        return D3DTEXF_POINT;
867
 
    } else /*if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0)*/ {
 
880
    } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
868
881
        return D3DTEXF_LINEAR;
869
882
    }
870
883
}
1014
1027
}
1015
1028
 
1016
1029
static int
 
1030
D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
 
1031
                     const SDL_Rect * rect,
 
1032
                     const Uint8 *Yplane, int Ypitch,
 
1033
                     const Uint8 *Uplane, int Upitch,
 
1034
                     const Uint8 *Vplane, int Vpitch)
 
1035
{
 
1036
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
 
1037
    SDL_bool full_texture = SDL_FALSE;
 
1038
 
 
1039
#ifdef USE_DYNAMIC_TEXTURE
 
1040
    if (texture->access == SDL_TEXTUREACCESS_STREAMING &&
 
1041
        rect->x == 0 && rect->y == 0 &&
 
1042
        rect->w == texture->w && rect->h == texture->h) {
 
1043
            full_texture = SDL_TRUE;
 
1044
    }
 
1045
#endif
 
1046
 
 
1047
    if (D3D_UpdateTextureInternal(data->texture, texture->format, full_texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
 
1048
        return -1;
 
1049
    }
 
1050
    if (D3D_UpdateTextureInternal(data->utexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch) < 0) {
 
1051
        return -1;
 
1052
    }
 
1053
    if (D3D_UpdateTextureInternal(data->vtexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch) < 0) {
 
1054
        return -1;
 
1055
    }
 
1056
    return 0;
 
1057
}
 
1058
 
 
1059
static int
1017
1060
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
1018
1061
                const SDL_Rect * rect, void **pixels, int *pitch)
1019
1062
{
1023
1066
    HRESULT result;
1024
1067
 
1025
1068
    if (data->yuv) {
1026
 
        // It's more efficient to upload directly...
 
1069
        /* It's more efficient to upload directly... */
1027
1070
        if (!data->pixels) {
1028
1071
            data->pitch = texture->w;
1029
1072
            data->pixels = (Uint8 *)SDL_malloc((texture->h * data->pitch * 3) / 2);
1173
1216
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1174
1217
    DWORD color;
1175
1218
    HRESULT result;
 
1219
    int BackBufferWidth, BackBufferHeight;
1176
1220
 
1177
1221
    if (D3D_ActivateRenderer(renderer) < 0) {
1178
1222
        return -1;
1180
1224
 
1181
1225
    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
1182
1226
 
 
1227
    if (renderer->target) {
 
1228
        BackBufferWidth = renderer->target->w;
 
1229
        BackBufferHeight = renderer->target->h;
 
1230
    } else {
 
1231
        BackBufferWidth = data->pparams.BackBufferWidth;
 
1232
        BackBufferHeight = data->pparams.BackBufferHeight;
 
1233
    }
 
1234
 
1183
1235
    /* Don't reset the viewport if we don't have to! */
1184
1236
    if (!renderer->viewport.x && !renderer->viewport.y &&
1185
 
        renderer->viewport.w == data->pparams.BackBufferWidth &&
1186
 
        renderer->viewport.h == data->pparams.BackBufferHeight) {
 
1237
        renderer->viewport.w == BackBufferWidth &&
 
1238
        renderer->viewport.h == BackBufferHeight) {
1187
1239
        result = IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
1188
1240
    } else {
1189
1241
        D3DVIEWPORT9 viewport;
1191
1243
        /* Clear is defined to clear the entire render target */
1192
1244
        viewport.X = 0;
1193
1245
        viewport.Y = 0;
1194
 
        viewport.Width = data->pparams.BackBufferWidth;
1195
 
        viewport.Height = data->pparams.BackBufferHeight;
 
1246
        viewport.Width = BackBufferWidth;
 
1247
        viewport.Height = BackBufferHeight;
1196
1248
        viewport.MinZ = 0.0f;
1197
1249
        viewport.MaxZ = 1.0f;
1198
1250
        IDirect3DDevice9_SetViewport(data->device, &viewport);
1803
1855
    if (data->vtexture) {
1804
1856
        IDirect3DTexture9_Release(data->vtexture);
1805
1857
    }
1806
 
    if (data->pixels) {
1807
 
        SDL_free(data->pixels);
1808
 
    }
 
1858
    SDL_free(data->pixels);
1809
1859
    SDL_free(data);
1810
1860
    texture->driverdata = NULL;
1811
1861
}
1825
1875
            IDirect3DSurface9_Release(data->currentRenderTarget);
1826
1876
            data->currentRenderTarget = NULL;
1827
1877
        }
1828
 
 
 
1878
        if (data->ps_yuv) {
 
1879
            IDirect3DPixelShader9_Release(data->ps_yuv);
 
1880
        }
1829
1881
        if (data->device) {
1830
1882
            IDirect3DDevice9_Release(data->device);
1831
1883
        }
1839
1891
    SDL_free(renderer);
1840
1892
}
1841
1893
 
 
1894
IDirect3DDevice9 *
 
1895
SDL_RenderGetD3D9Device(SDL_Renderer * renderer)
 
1896
{
 
1897
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
 
1898
    IDirect3DDevice9 *device;
 
1899
 
 
1900
    // Make sure that this is a D3D renderer
 
1901
    if (renderer->DestroyRenderer != D3D_DestroyRenderer) {
 
1902
        SDL_SetError("Renderer is not a D3D renderer");
 
1903
        return NULL;
 
1904
    }
 
1905
 
 
1906
    device = data->device;
 
1907
    if (device) {
 
1908
        IDirect3DDevice9_AddRef( device );
 
1909
    }
 
1910
    return device;
 
1911
}
 
1912
 
1842
1913
#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
1843
1914
 
1844
1915
/* vi: set ts=4 sw=4 expandtab: */