src/video/win32/SDL_d3drender.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 06 Dec 2009 06:21:39 +0000
changeset 3527 444cb12cadb6
parent 3520 83518f8fcd61
child 3536 0267b8b1595c
permissions -rw-r--r--
Fixed to use the correct display adapter
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@1895
     4
slouken@1895
     5
    This library is free software; you can redistribute it and/or
slouken@1895
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1895
     7
    License as published by the Free Software Foundation; either
slouken@1895
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1895
     9
slouken@1895
    10
    This library is distributed in the hope that it will be useful,
slouken@1895
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1895
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1895
    13
    Lesser General Public License for more details.
slouken@1895
    14
slouken@1895
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1895
    16
    License along with this library; if not, write to the Free Software
slouken@1895
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1895
    18
slouken@1895
    19
    Sam Lantinga
slouken@1895
    20
    slouken@libsdl.org
slouken@1895
    21
*/
slouken@1895
    22
#include "SDL_config.h"
slouken@1895
    23
slouken@1895
    24
#if SDL_VIDEO_RENDER_D3D
slouken@1895
    25
slouken@1895
    26
#include "SDL_win32video.h"
slouken@2973
    27
#include "../SDL_yuv_sw_c.h"
slouken@1895
    28
slouken@1895
    29
/* Direct3D renderer implementation */
slouken@1895
    30
slouken@2786
    31
#if 1                           /* This takes more memory but you won't lose your texture data */
slouken@2932
    32
#define D3DPOOL_SDL    D3DPOOL_MANAGED
slouken@2783
    33
#define SDL_MEMORY_POOL_MANAGED
slouken@2783
    34
#else
slouken@2932
    35
#define D3DPOOL_SDL    D3DPOOL_DEFAULT
slouken@2783
    36
#define SDL_MEMORY_POOL_DEFAULT
slouken@2783
    37
#endif
slouken@2783
    38
slouken@1913
    39
static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
slouken@1975
    40
static int D3D_DisplayModeChanged(SDL_Renderer * renderer);
slouken@1913
    41
static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@2990
    42
static int D3D_QueryTexturePixels(SDL_Renderer * renderer,
slouken@2990
    43
                                  SDL_Texture * texture, void **pixels,
slouken@2990
    44
                                  int *pitch);
slouken@1913
    45
static int D3D_SetTexturePalette(SDL_Renderer * renderer,
slouken@1913
    46
                                 SDL_Texture * texture,
slouken@1913
    47
                                 const SDL_Color * colors, int firstcolor,
slouken@1913
    48
                                 int ncolors);
slouken@1913
    49
static int D3D_GetTexturePalette(SDL_Renderer * renderer,
slouken@1913
    50
                                 SDL_Texture * texture, SDL_Color * colors,
slouken@1913
    51
                                 int firstcolor, int ncolors);
slouken@1985
    52
static int D3D_SetTextureColorMod(SDL_Renderer * renderer,
slouken@1985
    53
                                  SDL_Texture * texture);
slouken@1985
    54
static int D3D_SetTextureAlphaMod(SDL_Renderer * renderer,
slouken@1985
    55
                                  SDL_Texture * texture);
slouken@1985
    56
static int D3D_SetTextureBlendMode(SDL_Renderer * renderer,
slouken@1985
    57
                                   SDL_Texture * texture);
slouken@1985
    58
static int D3D_SetTextureScaleMode(SDL_Renderer * renderer,
slouken@1985
    59
                                   SDL_Texture * texture);
slouken@1913
    60
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
    61
                             const SDL_Rect * rect, const void *pixels,
slouken@1913
    62
                             int pitch);
slouken@1913
    63
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
    64
                           const SDL_Rect * rect, int markDirty,
slouken@1913
    65
                           void **pixels, int *pitch);
slouken@1913
    66
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@1913
    67
static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
    68
                             int numrects, const SDL_Rect * rects);
slouken@2932
    69
static int D3D_RenderPoint(SDL_Renderer * renderer, int x, int y);
slouken@2932
    70
static int D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
slouken@2932
    71
                          int y2);
slouken@2919
    72
static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
slouken@1913
    73
static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
    74
                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
slouken@3427
    75
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3480
    76
                                Uint32 format, void * pixels, int pitch);
slouken@3480
    77
static int D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3480
    78
                                 Uint32 format, const void * pixels, int pitch);
slouken@1913
    79
static void D3D_RenderPresent(SDL_Renderer * renderer);
slouken@1913
    80
static void D3D_DestroyTexture(SDL_Renderer * renderer,
slouken@1913
    81
                               SDL_Texture * texture);
slouken@1913
    82
static void D3D_DestroyRenderer(SDL_Renderer * renderer);
slouken@1895
    83
slouken@1895
    84
slouken@1913
    85
SDL_RenderDriver D3D_RenderDriver = {
slouken@1913
    86
    D3D_CreateRenderer,
slouken@1895
    87
    {
slouken@1895
    88
     "d3d",
slouken@1965
    89
     (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
slouken@1975
    90
      SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
slouken@1965
    91
      SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC |
slouken@1965
    92
      SDL_RENDERER_ACCELERATED),
slouken@1985
    93
     (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
slouken@1985
    94
      SDL_TEXTUREMODULATE_ALPHA),
slouken@2884
    95
     (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
slouken@2884
    96
      SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
slouken@1965
    97
     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
slouken@1965
    98
      SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
slouken@2972
    99
     0,
slouken@2972
   100
     {0},
slouken@1895
   101
     0,
slouken@1895
   102
     0}
slouken@1895
   103
};
slouken@1895
   104
slouken@1895
   105
typedef struct
slouken@1895
   106
{
slouken@2973
   107
    IDirect3D9 *d3d;
slouken@1895
   108
    IDirect3DDevice9 *device;
slouken@3527
   109
    UINT adapter;
slouken@1975
   110
    D3DPRESENT_PARAMETERS pparams;
slouken@1900
   111
    SDL_bool beginScene;
slouken@1913
   112
} D3D_RenderData;
slouken@1895
   113
slouken@1895
   114
typedef struct
slouken@1895
   115
{
slouken@2973
   116
    SDL_SW_YUVTexture *yuv;
slouken@2973
   117
    Uint32 format;
slouken@1903
   118
    IDirect3DTexture9 *texture;
slouken@1913
   119
} D3D_TextureData;
slouken@1895
   120
slouken@1903
   121
typedef struct
slouken@1903
   122
{
slouken@1903
   123
    float x, y, z;
slouken@1904
   124
    float rhw;
slouken@1987
   125
    DWORD color;
slouken@1904
   126
    float u, v;
slouken@1903
   127
} Vertex;
slouken@1903
   128
slouken@1895
   129
static void
slouken@1900
   130
D3D_SetError(const char *prefix, HRESULT result)
slouken@1900
   131
{
slouken@1900
   132
    const char *error;
slouken@1900
   133
slouken@1900
   134
    switch (result) {
slouken@1900
   135
    case D3DERR_WRONGTEXTUREFORMAT:
slouken@1900
   136
        error = "WRONGTEXTUREFORMAT";
slouken@1900
   137
        break;
slouken@1900
   138
    case D3DERR_UNSUPPORTEDCOLOROPERATION:
slouken@1900
   139
        error = "UNSUPPORTEDCOLOROPERATION";
slouken@1900
   140
        break;
slouken@1900
   141
    case D3DERR_UNSUPPORTEDCOLORARG:
slouken@1900
   142
        error = "UNSUPPORTEDCOLORARG";
slouken@1900
   143
        break;
slouken@1900
   144
    case D3DERR_UNSUPPORTEDALPHAOPERATION:
slouken@1900
   145
        error = "UNSUPPORTEDALPHAOPERATION";
slouken@1900
   146
        break;
slouken@1900
   147
    case D3DERR_UNSUPPORTEDALPHAARG:
slouken@1900
   148
        error = "UNSUPPORTEDALPHAARG";
slouken@1900
   149
        break;
slouken@1900
   150
    case D3DERR_TOOMANYOPERATIONS:
slouken@1900
   151
        error = "TOOMANYOPERATIONS";
slouken@1900
   152
        break;
slouken@1900
   153
    case D3DERR_CONFLICTINGTEXTUREFILTER:
slouken@1900
   154
        error = "CONFLICTINGTEXTUREFILTER";
slouken@1900
   155
        break;
slouken@1900
   156
    case D3DERR_UNSUPPORTEDFACTORVALUE:
slouken@1900
   157
        error = "UNSUPPORTEDFACTORVALUE";
slouken@1900
   158
        break;
slouken@1900
   159
    case D3DERR_CONFLICTINGRENDERSTATE:
slouken@1900
   160
        error = "CONFLICTINGRENDERSTATE";
slouken@1900
   161
        break;
slouken@1900
   162
    case D3DERR_UNSUPPORTEDTEXTUREFILTER:
slouken@1900
   163
        error = "UNSUPPORTEDTEXTUREFILTER";
slouken@1900
   164
        break;
slouken@1900
   165
    case D3DERR_CONFLICTINGTEXTUREPALETTE:
slouken@1900
   166
        error = "CONFLICTINGTEXTUREPALETTE";
slouken@1900
   167
        break;
slouken@1900
   168
    case D3DERR_DRIVERINTERNALERROR:
slouken@1900
   169
        error = "DRIVERINTERNALERROR";
slouken@1900
   170
        break;
slouken@1900
   171
    case D3DERR_NOTFOUND:
slouken@1900
   172
        error = "NOTFOUND";
slouken@1900
   173
        break;
slouken@1900
   174
    case D3DERR_MOREDATA:
slouken@1900
   175
        error = "MOREDATA";
slouken@1900
   176
        break;
slouken@1900
   177
    case D3DERR_DEVICELOST:
slouken@1900
   178
        error = "DEVICELOST";
slouken@1900
   179
        break;
slouken@1900
   180
    case D3DERR_DEVICENOTRESET:
slouken@1900
   181
        error = "DEVICENOTRESET";
slouken@1900
   182
        break;
slouken@1900
   183
    case D3DERR_NOTAVAILABLE:
slouken@1900
   184
        error = "NOTAVAILABLE";
slouken@1900
   185
        break;
slouken@1900
   186
    case D3DERR_OUTOFVIDEOMEMORY:
slouken@1900
   187
        error = "OUTOFVIDEOMEMORY";
slouken@1900
   188
        break;
slouken@1900
   189
    case D3DERR_INVALIDDEVICE:
slouken@1900
   190
        error = "INVALIDDEVICE";
slouken@1900
   191
        break;
slouken@1900
   192
    case D3DERR_INVALIDCALL:
slouken@1900
   193
        error = "INVALIDCALL";
slouken@1900
   194
        break;
slouken@1900
   195
    case D3DERR_DRIVERINVALIDCALL:
slouken@1900
   196
        error = "DRIVERINVALIDCALL";
slouken@1900
   197
        break;
slouken@1900
   198
    case D3DERR_WASSTILLDRAWING:
slouken@1900
   199
        error = "WASSTILLDRAWING";
slouken@1900
   200
        break;
slouken@1900
   201
    default:
slouken@1900
   202
        error = "UNKNOWN";
slouken@1900
   203
        break;
slouken@1900
   204
    }
slouken@1900
   205
    SDL_SetError("%s: %s", prefix, error);
slouken@1900
   206
}
slouken@1900
   207
slouken@1903
   208
static D3DFORMAT
slouken@1903
   209
PixelFormatToD3DFMT(Uint32 format)
slouken@1895
   210
{
slouken@1903
   211
    switch (format) {
slouken@1965
   212
    case SDL_PIXELFORMAT_INDEX8:
slouken@1903
   213
        return D3DFMT_P8;
slouken@1965
   214
    case SDL_PIXELFORMAT_RGB332:
slouken@1903
   215
        return D3DFMT_R3G3B2;
slouken@1965
   216
    case SDL_PIXELFORMAT_RGB444:
slouken@1903
   217
        return D3DFMT_X4R4G4B4;
slouken@1965
   218
    case SDL_PIXELFORMAT_RGB555:
slouken@1903
   219
        return D3DFMT_X1R5G5B5;
slouken@1965
   220
    case SDL_PIXELFORMAT_ARGB4444:
slouken@1903
   221
        return D3DFMT_A4R4G4B4;
slouken@1965
   222
    case SDL_PIXELFORMAT_ARGB1555:
slouken@1903
   223
        return D3DFMT_A1R5G5B5;
slouken@1965
   224
    case SDL_PIXELFORMAT_RGB565:
slouken@1903
   225
        return D3DFMT_R5G6B5;
slouken@1965
   226
    case SDL_PIXELFORMAT_RGB888:
slouken@1903
   227
        return D3DFMT_X8R8G8B8;
slouken@1965
   228
    case SDL_PIXELFORMAT_ARGB8888:
slouken@1903
   229
        return D3DFMT_A8R8G8B8;
slouken@1965
   230
    case SDL_PIXELFORMAT_ARGB2101010:
slouken@1903
   231
        return D3DFMT_A2R10G10B10;
slouken@3495
   232
    case SDL_PIXELFORMAT_YV12:
slouken@3495
   233
        return MAKEFOURCC('Y','V','1','2');
slouken@3495
   234
    case SDL_PIXELFORMAT_IYUV:
slouken@3495
   235
        return MAKEFOURCC('I','4','2','0');
slouken@1965
   236
    case SDL_PIXELFORMAT_UYVY:
slouken@1903
   237
        return D3DFMT_UYVY;
slouken@1965
   238
    case SDL_PIXELFORMAT_YUY2:
slouken@1903
   239
        return D3DFMT_YUY2;
slouken@1903
   240
    default:
slouken@1903
   241
        return D3DFMT_UNKNOWN;
slouken@1903
   242
    }
slouken@1895
   243
}
slouken@1895
   244
slouken@3527
   245
static UINT D3D_FindAdapter(IDirect3D9 * d3d, SDL_VideoDisplay * display)
slouken@3527
   246
{
slouken@3527
   247
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
slouken@3527
   248
    UINT adapter, count;
slouken@3527
   249
slouken@3527
   250
    count = IDirect3D9_GetAdapterCount(d3d);
slouken@3527
   251
    for (adapter = 0; adapter < count; ++adapter) {
slouken@3527
   252
        HRESULT result;
slouken@3527
   253
        D3DADAPTER_IDENTIFIER9 info;
slouken@3527
   254
        char *name;
slouken@3527
   255
slouken@3527
   256
        result = IDirect3D9_GetAdapterIdentifier(d3d, adapter, 0, &info);
slouken@3527
   257
        if (FAILED(result)) {
slouken@3527
   258
            continue;
slouken@3527
   259
        }
slouken@3527
   260
        name = WIN_StringToUTF8(displaydata->DeviceName);
slouken@3527
   261
        if (SDL_strcmp(name, info.DeviceName) == 0) {
slouken@3527
   262
            SDL_free(name);
slouken@3527
   263
            return adapter;
slouken@3527
   264
        }
slouken@3527
   265
        SDL_free(name);
slouken@3527
   266
    }
slouken@3527
   267
slouken@3527
   268
    /* This should never happen, but just in case... */
slouken@3527
   269
    return D3DADAPTER_DEFAULT;
slouken@3527
   270
}
slouken@3527
   271
slouken@2973
   272
static SDL_bool
slouken@3527
   273
D3D_IsTextureFormatAvailable(IDirect3D9 * d3d, UINT adapter,
slouken@3527
   274
                             Uint32 display_format,
slouken@2990
   275
                             Uint32 texture_format)
slouken@2973
   276
{
slouken@2973
   277
    HRESULT result;
slouken@2973
   278
slouken@3527
   279
    result = IDirect3D9_CheckDeviceFormat(d3d, adapter,
slouken@2973
   280
                                          D3DDEVTYPE_HAL,
slouken@2973
   281
                                          PixelFormatToD3DFMT(display_format),
slouken@2973
   282
                                          0,
slouken@2973
   283
                                          D3DRTYPE_TEXTURE,
slouken@2990
   284
                                          PixelFormatToD3DFMT
slouken@2990
   285
                                          (texture_format));
slouken@2973
   286
    return FAILED(result) ? SDL_FALSE : SDL_TRUE;
slouken@2973
   287
}
slouken@2973
   288
slouken@2973
   289
static void
slouken@2973
   290
UpdateYUVTextureData(SDL_Texture * texture)
slouken@2973
   291
{
slouken@2973
   292
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@2973
   293
    SDL_Rect rect;
slouken@2973
   294
    RECT d3drect;
slouken@2973
   295
    D3DLOCKED_RECT locked;
slouken@2973
   296
    HRESULT result;
slouken@2973
   297
slouken@2973
   298
    d3drect.left = 0;
slouken@2973
   299
    d3drect.right = texture->w;
slouken@2973
   300
    d3drect.top = 0;
slouken@2973
   301
    d3drect.bottom = texture->h;
slouken@2973
   302
slouken@2990
   303
    result =
slouken@2990
   304
        IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
slouken@2973
   305
    if (FAILED(result)) {
slouken@2973
   306
        return;
slouken@2973
   307
    }
slouken@2973
   308
slouken@2973
   309
    rect.x = 0;
slouken@2973
   310
    rect.y = 0;
slouken@2973
   311
    rect.w = texture->w;
slouken@2973
   312
    rect.h = texture->h;
slouken@2973
   313
    SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
slouken@2973
   314
                        texture->h, locked.pBits, locked.Pitch);
slouken@2973
   315
slouken@2973
   316
    IDirect3DTexture9_UnlockRect(data->texture, 0);
slouken@2973
   317
}
slouken@2973
   318
slouken@1895
   319
void
slouken@1895
   320
D3D_AddRenderDriver(_THIS)
slouken@1895
   321
{
slouken@1895
   322
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@2972
   323
    SDL_RendererInfo *info = &D3D_RenderDriver.info;
slouken@1895
   324
slouken@1895
   325
    if (data->d3d) {
slouken@3527
   326
        int i, j;
slouken@2972
   327
        int formats[] = {
slouken@2990
   328
            SDL_PIXELFORMAT_INDEX8,
slouken@2990
   329
            SDL_PIXELFORMAT_RGB332,
slouken@2990
   330
            SDL_PIXELFORMAT_RGB444,
slouken@2990
   331
            SDL_PIXELFORMAT_RGB555,
slouken@2990
   332
            SDL_PIXELFORMAT_ARGB4444,
slouken@2990
   333
            SDL_PIXELFORMAT_ARGB1555,
slouken@2990
   334
            SDL_PIXELFORMAT_RGB565,
slouken@2990
   335
            SDL_PIXELFORMAT_RGB888,
slouken@2990
   336
            SDL_PIXELFORMAT_ARGB8888,
slouken@2990
   337
            SDL_PIXELFORMAT_ARGB2101010,
slouken@2972
   338
        };
slouken@2972
   339
slouken@3527
   340
        for (i = 0; i < _this->num_displays; ++i) {
slouken@3527
   341
            SDL_VideoDisplay *display = &_this->displays[i];
slouken@3527
   342
            SDL_DisplayMode *mode = &display->desktop_mode;
slouken@3527
   343
            UINT adapter = D3D_FindAdapter(data->d3d, display);
slouken@3527
   344
slouken@3527
   345
            /* Get the matching D3D adapter for this display */
slouken@3527
   346
            info->num_texture_formats = 0;
slouken@3527
   347
            for (j = 0; j < SDL_arraysize(formats); ++j) {
slouken@3527
   348
                if (D3D_IsTextureFormatAvailable
slouken@3527
   349
                    (data->d3d, adapter, mode->format, formats[j])) {
slouken@3527
   350
                    info->texture_formats[info->num_texture_formats++] =
slouken@3527
   351
                        formats[j];
slouken@3527
   352
                }
slouken@2972
   353
            }
slouken@3527
   354
            info->texture_formats[info->num_texture_formats++] =
slouken@3527
   355
                SDL_PIXELFORMAT_YV12;
slouken@3527
   356
            info->texture_formats[info->num_texture_formats++] =
slouken@3527
   357
                SDL_PIXELFORMAT_IYUV;
slouken@3527
   358
            info->texture_formats[info->num_texture_formats++] =
slouken@3527
   359
                SDL_PIXELFORMAT_YUY2;
slouken@3527
   360
            info->texture_formats[info->num_texture_formats++] =
slouken@3527
   361
                SDL_PIXELFORMAT_UYVY;
slouken@3527
   362
            info->texture_formats[info->num_texture_formats++] =
slouken@3527
   363
                SDL_PIXELFORMAT_YVYU;
slouken@2972
   364
slouken@3527
   365
            SDL_AddRenderDriver(display, &D3D_RenderDriver);
slouken@3520
   366
        }
slouken@1895
   367
    }
slouken@1895
   368
}
slouken@1895
   369
slouken@1895
   370
SDL_Renderer *
slouken@1913
   371
D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
slouken@1895
   372
{
slouken@1895
   373
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@1895
   374
    SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
slouken@1895
   375
    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
slouken@1895
   376
    SDL_Renderer *renderer;
slouken@1913
   377
    D3D_RenderData *data;
slouken@1900
   378
    HRESULT result;
slouken@1900
   379
    D3DPRESENT_PARAMETERS pparams;
slouken@1907
   380
    IDirect3DSwapChain9 *chain;
slouken@1925
   381
    D3DCAPS9 caps;
slouken@1895
   382
slouken@1920
   383
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
slouken@1895
   384
    if (!renderer) {
slouken@1895
   385
        SDL_OutOfMemory();
slouken@1895
   386
        return NULL;
slouken@1895
   387
    }
slouken@1895
   388
slouken@1920
   389
    data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
slouken@1895
   390
    if (!data) {
slouken@1913
   391
        D3D_DestroyRenderer(renderer);
slouken@1895
   392
        SDL_OutOfMemory();
slouken@1895
   393
        return NULL;
slouken@1895
   394
    }
slouken@2973
   395
    data->d3d = videodata->d3d;
slouken@1895
   396
slouken@1975
   397
    renderer->DisplayModeChanged = D3D_DisplayModeChanged;
slouken@1913
   398
    renderer->CreateTexture = D3D_CreateTexture;
slouken@2973
   399
    renderer->QueryTexturePixels = D3D_QueryTexturePixels;
slouken@1913
   400
    renderer->SetTexturePalette = D3D_SetTexturePalette;
slouken@1913
   401
    renderer->GetTexturePalette = D3D_GetTexturePalette;
slouken@1985
   402
    renderer->SetTextureColorMod = D3D_SetTextureColorMod;
slouken@1985
   403
    renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod;
slouken@1985
   404
    renderer->SetTextureBlendMode = D3D_SetTextureBlendMode;
slouken@1985
   405
    renderer->SetTextureScaleMode = D3D_SetTextureScaleMode;
slouken@1913
   406
    renderer->UpdateTexture = D3D_UpdateTexture;
slouken@1913
   407
    renderer->LockTexture = D3D_LockTexture;
slouken@1913
   408
    renderer->UnlockTexture = D3D_UnlockTexture;
slouken@1913
   409
    renderer->DirtyTexture = D3D_DirtyTexture;
slouken@2932
   410
    renderer->RenderPoint = D3D_RenderPoint;
slouken@2932
   411
    renderer->RenderLine = D3D_RenderLine;
slouken@1913
   412
    renderer->RenderFill = D3D_RenderFill;
slouken@1913
   413
    renderer->RenderCopy = D3D_RenderCopy;
slouken@3427
   414
    renderer->RenderReadPixels = D3D_RenderReadPixels;
slouken@3480
   415
    renderer->RenderWritePixels = D3D_RenderWritePixels;
slouken@1913
   416
    renderer->RenderPresent = D3D_RenderPresent;
slouken@1913
   417
    renderer->DestroyTexture = D3D_DestroyTexture;
slouken@1913
   418
    renderer->DestroyRenderer = D3D_DestroyRenderer;
slouken@1913
   419
    renderer->info = D3D_RenderDriver.info;
slouken@1895
   420
    renderer->window = window->id;
slouken@1895
   421
    renderer->driverdata = data;
slouken@1895
   422
slouken@1965
   423
    renderer->info.flags = SDL_RENDERER_ACCELERATED;
slouken@1895
   424
slouken@1900
   425
    SDL_zero(pparams);
slouken@1900
   426
    pparams.BackBufferWidth = window->w;
slouken@1900
   427
    pparams.BackBufferHeight = window->h;
slouken@1903
   428
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1903
   429
        pparams.BackBufferFormat =
slouken@3519
   430
            PixelFormatToD3DFMT(window->fullscreen_mode.format);
slouken@1903
   431
    } else {
slouken@1903
   432
        pparams.BackBufferFormat = D3DFMT_UNKNOWN;
slouken@1903
   433
    }
slouken@1965
   434
    if (flags & SDL_RENDERER_PRESENTFLIP2) {
slouken@1900
   435
        pparams.BackBufferCount = 2;
slouken@1900
   436
        pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
slouken@1965
   437
    } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
slouken@1900
   438
        pparams.BackBufferCount = 3;
slouken@1900
   439
        pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
slouken@1965
   440
    } else if (flags & SDL_RENDERER_PRESENTCOPY) {
slouken@1900
   441
        pparams.BackBufferCount = 1;
slouken@1900
   442
        pparams.SwapEffect = D3DSWAPEFFECT_COPY;
slouken@1900
   443
    } else {
slouken@1900
   444
        pparams.BackBufferCount = 1;
slouken@1900
   445
        pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
slouken@1900
   446
    }
slouken@1900
   447
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1900
   448
        pparams.Windowed = FALSE;
slouken@1903
   449
        pparams.FullScreen_RefreshRateInHz =
slouken@3519
   450
            window->fullscreen_mode.refresh_rate;
slouken@1900
   451
    } else {
slouken@1900
   452
        pparams.Windowed = TRUE;
slouken@1903
   453
        pparams.FullScreen_RefreshRateInHz = 0;
slouken@1900
   454
    }
slouken@1965
   455
    if (flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@1907
   456
        pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
slouken@1907
   457
    } else {
slouken@1907
   458
        pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
slouken@1907
   459
    }
slouken@1900
   460
slouken@3527
   461
    data->adapter = D3D_FindAdapter(videodata->d3d, display);
slouken@3527
   462
    IDirect3D9_GetDeviceCaps(videodata->d3d, data->adapter,
slouken@3197
   463
                             D3DDEVTYPE_HAL, &caps);
slouken@3197
   464
slouken@3527
   465
    result = IDirect3D9_CreateDevice(videodata->d3d, data->adapter,
slouken@1900
   466
                                     D3DDEVTYPE_HAL,
slouken@1900
   467
                                     windowdata->hwnd,
slouken@3197
   468
                                     (caps.
slouken@3197
   469
                                      DevCaps &
slouken@3197
   470
                                      D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
slouken@3197
   471
                                     D3DCREATE_HARDWARE_VERTEXPROCESSING :
slouken@1900
   472
                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
slouken@1900
   473
                                     &pparams, &data->device);
slouken@1900
   474
    if (FAILED(result)) {
slouken@1913
   475
        D3D_DestroyRenderer(renderer);
slouken@1900
   476
        D3D_SetError("CreateDevice()", result);
slouken@1900
   477
        return NULL;
slouken@1900
   478
    }
slouken@1900
   479
    data->beginScene = SDL_TRUE;
slouken@1900
   480
slouken@1907
   481
    /* Get presentation parameters to fill info */
slouken@1907
   482
    result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
slouken@1907
   483
    if (FAILED(result)) {
slouken@1913
   484
        D3D_DestroyRenderer(renderer);
slouken@1907
   485
        D3D_SetError("GetSwapChain()", result);
slouken@1907
   486
        return NULL;
slouken@1907
   487
    }
slouken@1907
   488
    result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
slouken@1907
   489
    if (FAILED(result)) {
slouken@1907
   490
        IDirect3DSwapChain9_Release(chain);
slouken@1913
   491
        D3D_DestroyRenderer(renderer);
slouken@1907
   492
        D3D_SetError("GetPresentParameters()", result);
slouken@1907
   493
        return NULL;
slouken@1907
   494
    }
slouken@1907
   495
    IDirect3DSwapChain9_Release(chain);
slouken@1907
   496
    switch (pparams.SwapEffect) {
slouken@1907
   497
    case D3DSWAPEFFECT_COPY:
slouken@1965
   498
        renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
slouken@1907
   499
        break;
slouken@1907
   500
    case D3DSWAPEFFECT_FLIP:
slouken@1907
   501
        switch (pparams.BackBufferCount) {
slouken@1907
   502
        case 2:
slouken@1965
   503
            renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
slouken@1907
   504
            break;
slouken@1907
   505
        case 3:
slouken@1965
   506
            renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
slouken@1907
   507
            break;
slouken@1907
   508
        }
slouken@1907
   509
        break;
slouken@1907
   510
    case D3DSWAPEFFECT_DISCARD:
slouken@1965
   511
        renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD;
slouken@1907
   512
        break;
slouken@1907
   513
    }
slouken@1907
   514
    if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
slouken@1965
   515
        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
slouken@1907
   516
    }
slouken@1975
   517
    data->pparams = pparams;
slouken@1907
   518
slouken@1925
   519
    IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
slouken@1925
   520
    renderer->info.max_texture_width = caps.MaxTextureWidth;
slouken@1925
   521
    renderer->info.max_texture_height = caps.MaxTextureHeight;
slouken@1918
   522
slouken@1903
   523
    /* Set up parameters for rendering */
slouken@1904
   524
    IDirect3DDevice9_SetVertexShader(data->device, NULL);
slouken@1987
   525
    IDirect3DDevice9_SetFVF(data->device,
slouken@1987
   526
                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
slouken@1988
   527
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
slouken@1903
   528
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
slouken@1903
   529
                                    D3DCULL_NONE);
slouken@1904
   530
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
slouken@1988
   531
    /* Enable color modulation by diffuse color */
slouken@1988
   532
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
slouken@1988
   533
                                          D3DTOP_MODULATE);
slouken@1988
   534
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
slouken@1988
   535
                                          D3DTA_TEXTURE);
slouken@1988
   536
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
slouken@1988
   537
                                          D3DTA_DIFFUSE);
slouken@1988
   538
    /* Enable alpha modulation by diffuse alpha */
slouken@1988
   539
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
slouken@1988
   540
                                          D3DTOP_MODULATE);
slouken@1988
   541
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
slouken@1988
   542
                                          D3DTA_TEXTURE);
slouken@1988
   543
    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
slouken@1988
   544
                                          D3DTA_DIFFUSE);
slouken@1991
   545
    /* Disable second texture stage, since we're done */
slouken@1991
   546
    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
slouken@1991
   547
                                          D3DTOP_DISABLE);
slouken@1991
   548
    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
slouken@1991
   549
                                          D3DTOP_DISABLE);
slouken@1903
   550
slouken@1895
   551
    return renderer;
slouken@1895
   552
}
slouken@1895
   553
slouken@1895
   554
static int
slouken@1975
   555
D3D_Reset(SDL_Renderer * renderer)
slouken@1975
   556
{
slouken@1975
   557
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@1975
   558
    HRESULT result;
slouken@1975
   559
slouken@1975
   560
    result = IDirect3DDevice9_Reset(data->device, &data->pparams);
slouken@1975
   561
    if (FAILED(result)) {
slouken@1975
   562
        if (result == D3DERR_DEVICELOST) {
slouken@1975
   563
            /* Don't worry about it, we'll reset later... */
slouken@1975
   564
            return 0;
slouken@1975
   565
        } else {
slouken@1975
   566
            D3D_SetError("Reset()", result);
slouken@1975
   567
            return -1;
slouken@1975
   568
        }
slouken@1975
   569
    }
slouken@1975
   570
    IDirect3DDevice9_SetVertexShader(data->device, NULL);
slouken@1987
   571
    IDirect3DDevice9_SetFVF(data->device,
slouken@1987
   572
                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
slouken@1975
   573
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
slouken@1975
   574
                                    D3DCULL_NONE);
slouken@1975
   575
    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
slouken@1975
   576
    return 0;
slouken@1975
   577
}
slouken@1975
   578
slouken@1975
   579
static int
slouken@1975
   580
D3D_DisplayModeChanged(SDL_Renderer * renderer)
slouken@1975
   581
{
slouken@1975
   582
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@1975
   583
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
slouken@1975
   584
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@1975
   585
slouken@1975
   586
    data->pparams.BackBufferWidth = window->w;
slouken@1975
   587
    data->pparams.BackBufferHeight = window->h;
slouken@1975
   588
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1975
   589
        data->pparams.BackBufferFormat =
slouken@3519
   590
            PixelFormatToD3DFMT(window->fullscreen_mode.format);
slouken@1975
   591
    } else {
slouken@1975
   592
        data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
slouken@1975
   593
    }
slouken@1975
   594
    return D3D_Reset(renderer);
slouken@1975
   595
}
slouken@1975
   596
slouken@1975
   597
static int
slouken@1913
   598
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
   599
{
slouken@1913
   600
    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
slouken@1895
   601
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
slouken@1895
   602
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@2973
   603
    Uint32 display_format = display->current_mode.format;
slouken@1913
   604
    D3D_TextureData *data;
slouken@1903
   605
    HRESULT result;
slouken@1895
   606
slouken@1920
   607
    data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
slouken@1895
   608
    if (!data) {
slouken@1895
   609
        SDL_OutOfMemory();
slouken@1895
   610
        return -1;
slouken@1895
   611
    }
slouken@1895
   612
slouken@1895
   613
    texture->driverdata = data;
slouken@1895
   614
slouken@2973
   615
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format) &&
slouken@2973
   616
        (texture->format != SDL_PIXELFORMAT_YUY2 ||
slouken@3527
   617
         !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter,
slouken@3527
   618
                                       display_format, texture->format))
slouken@2990
   619
        && (texture->format != SDL_PIXELFORMAT_YVYU
slouken@3527
   620
            || !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter,
slouken@3527
   621
                                             display_format, texture->format))) {
slouken@2973
   622
        data->yuv =
slouken@2973
   623
            SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
slouken@2973
   624
        if (!data->yuv) {
slouken@2973
   625
            return -1;
slouken@2973
   626
        }
slouken@2973
   627
        data->format = display->current_mode.format;
slouken@2973
   628
    } else {
slouken@2973
   629
        data->format = texture->format;
slouken@2973
   630
    }
slouken@2973
   631
slouken@1903
   632
    result =
slouken@1903
   633
        IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
slouken@1903
   634
                                       texture->h, 1, 0,
slouken@2973
   635
                                       PixelFormatToD3DFMT(data->format),
slouken@2783
   636
                                       D3DPOOL_SDL, &data->texture, NULL);
slouken@1903
   637
    if (FAILED(result)) {
slouken@1903
   638
        D3D_SetError("CreateTexture()", result);
slouken@1903
   639
        return -1;
slouken@1903
   640
    }
slouken@1903
   641
slouken@1895
   642
    return 0;
slouken@1895
   643
}
slouken@1895
   644
slouken@1895
   645
static int
slouken@2973
   646
D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2973
   647
                       void **pixels, int *pitch)
slouken@2973
   648
{
slouken@2973
   649
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@2973
   650
slouken@2973
   651
    if (data->yuv) {
slouken@2973
   652
        return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
slouken@2973
   653
    } else {
slouken@2973
   654
        /* D3D textures don't have their pixels hanging out */
slouken@2973
   655
        return -1;
slouken@2973
   656
    }
slouken@2973
   657
}
slouken@2973
   658
slouken@2973
   659
static int
slouken@1913
   660
D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
   661
                      const SDL_Color * colors, int firstcolor, int ncolors)
slouken@1895
   662
{
slouken@1913
   663
    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
slouken@1913
   664
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1895
   665
slouken@1903
   666
    return 0;
slouken@1895
   667
}
slouken@1895
   668
slouken@1895
   669
static int
slouken@1913
   670
D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
   671
                      SDL_Color * colors, int firstcolor, int ncolors)
slouken@1895
   672
{
slouken@1913
   673
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1895
   674
slouken@1903
   675
    return 0;
slouken@1895
   676
}
slouken@1895
   677
slouken@1895
   678
static int
slouken@1985
   679
D3D_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   680
{
slouken@1987
   681
    return 0;
slouken@1985
   682
}
slouken@1985
   683
slouken@1985
   684
static int
slouken@1985
   685
D3D_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   686
{
slouken@1987
   687
    return 0;
slouken@1985
   688
}
slouken@1985
   689
slouken@1985
   690
static int
slouken@1985
   691
D3D_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   692
{
slouken@1985
   693
    switch (texture->blendMode) {
slouken@2884
   694
    case SDL_BLENDMODE_NONE:
slouken@2884
   695
    case SDL_BLENDMODE_MASK:
slouken@2884
   696
    case SDL_BLENDMODE_BLEND:
slouken@2884
   697
    case SDL_BLENDMODE_ADD:
slouken@2884
   698
    case SDL_BLENDMODE_MOD:
slouken@1985
   699
        return 0;
slouken@1985
   700
    default:
slouken@1985
   701
        SDL_Unsupported();
slouken@2884
   702
        texture->blendMode = SDL_BLENDMODE_NONE;
slouken@1985
   703
        return -1;
slouken@1985
   704
    }
slouken@1985
   705
}
slouken@1985
   706
slouken@1985
   707
static int
slouken@1985
   708
D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   709
{
slouken@1985
   710
    switch (texture->scaleMode) {
slouken@1985
   711
    case SDL_TEXTURESCALEMODE_NONE:
slouken@1985
   712
    case SDL_TEXTURESCALEMODE_FAST:
slouken@1985
   713
    case SDL_TEXTURESCALEMODE_SLOW:
slouken@1985
   714
    case SDL_TEXTURESCALEMODE_BEST:
slouken@1985
   715
        return 0;
slouken@1985
   716
    default:
slouken@1985
   717
        SDL_Unsupported();
slouken@1985
   718
        texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
slouken@1985
   719
        return -1;
slouken@1985
   720
    }
slouken@1985
   721
    return 0;
slouken@1985
   722
}
slouken@1985
   723
slouken@1985
   724
static int
slouken@1913
   725
D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
   726
                  const SDL_Rect * rect, const void *pixels, int pitch)
slouken@1895
   727
{
slouken@1913
   728
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1913
   729
    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
slouken@1895
   730
slouken@2973
   731
    if (data->yuv) {
slouken@2973
   732
        if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
slouken@2973
   733
            return -1;
slouken@2973
   734
        }
slouken@2973
   735
        UpdateYUVTextureData(texture);
slouken@2973
   736
        return 0;
slouken@2973
   737
    } else {
slouken@2973
   738
#ifdef SDL_MEMORY_POOL_DEFAULT
slouken@2973
   739
        IDirect3DTexture9 *temp;
slouken@2973
   740
        RECT d3drect;
slouken@2973
   741
        D3DLOCKED_RECT locked;
slouken@2973
   742
        const Uint8 *src;
slouken@2973
   743
        Uint8 *dst;
slouken@2973
   744
        int row, length;
slouken@2973
   745
        HRESULT result;
slouken@2973
   746
slouken@2973
   747
        result =
slouken@2973
   748
            IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
slouken@2973
   749
                                           texture->h, 1, 0,
slouken@3013
   750
                                           PixelFormatToD3DFMT(texture->
slouken@3013
   751
                                                               format),
slouken@2973
   752
                                           D3DPOOL_SYSTEMMEM, &temp, NULL);
slouken@2973
   753
        if (FAILED(result)) {
slouken@2973
   754
            D3D_SetError("CreateTexture()", result);
slouken@2973
   755
            return -1;
slouken@2973
   756
        }
slouken@2973
   757
slouken@2973
   758
        d3drect.left = rect->x;
slouken@2973
   759
        d3drect.right = rect->x + rect->w;
slouken@2973
   760
        d3drect.top = rect->y;
slouken@2973
   761
        d3drect.bottom = rect->y + rect->h;
slouken@2973
   762
slouken@2973
   763
        result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
slouken@2973
   764
        if (FAILED(result)) {
slouken@2973
   765
            IDirect3DTexture9_Release(temp);
slouken@2973
   766
            D3D_SetError("LockRect()", result);
slouken@2973
   767
            return -1;
slouken@2973
   768
        }
slouken@2973
   769
slouken@2973
   770
        src = pixels;
slouken@2973
   771
        dst = locked.pBits;
slouken@2973
   772
        length = rect->w * SDL_BYTESPERPIXEL(texture->format);
slouken@2973
   773
        for (row = 0; row < rect->h; ++row) {
slouken@2973
   774
            SDL_memcpy(dst, src, length);
slouken@2973
   775
            src += pitch;
slouken@2973
   776
            dst += locked.Pitch;
slouken@2973
   777
        }
slouken@2973
   778
        IDirect3DTexture9_UnlockRect(temp, 0);
slouken@2973
   779
slouken@2973
   780
        result =
slouken@2973
   781
            IDirect3DDevice9_UpdateTexture(renderdata->device,
slouken@2973
   782
                                           (IDirect3DBaseTexture9 *) temp,
slouken@2973
   783
                                           (IDirect3DBaseTexture9 *)
slouken@2973
   784
                                           data->texture);
slouken@2973
   785
        IDirect3DTexture9_Release(temp);
slouken@2973
   786
        if (FAILED(result)) {
slouken@2973
   787
            D3D_SetError("UpdateTexture()", result);
slouken@2973
   788
            return -1;
slouken@2973
   789
        }
slouken@2973
   790
#else
slouken@2973
   791
        RECT d3drect;
slouken@2973
   792
        D3DLOCKED_RECT locked;
slouken@2973
   793
        const Uint8 *src;
slouken@2973
   794
        Uint8 *dst;
slouken@2973
   795
        int row, length;
slouken@2973
   796
        HRESULT result;
slouken@2973
   797
slouken@2973
   798
        d3drect.left = rect->x;
slouken@2973
   799
        d3drect.right = rect->x + rect->w;
slouken@2973
   800
        d3drect.top = rect->y;
slouken@2973
   801
        d3drect.bottom = rect->y + rect->h;
slouken@2973
   802
slouken@2973
   803
        result =
slouken@2990
   804
            IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
slouken@2990
   805
                                       0);
slouken@2973
   806
        if (FAILED(result)) {
slouken@2973
   807
            D3D_SetError("LockRect()", result);
slouken@2973
   808
            return -1;
slouken@2973
   809
        }
slouken@2973
   810
slouken@2973
   811
        src = pixels;
slouken@2973
   812
        dst = locked.pBits;
slouken@2973
   813
        length = rect->w * SDL_BYTESPERPIXEL(texture->format);
slouken@2973
   814
        for (row = 0; row < rect->h; ++row) {
slouken@2973
   815
            SDL_memcpy(dst, src, length);
slouken@2973
   816
            src += pitch;
slouken@2973
   817
            dst += locked.Pitch;
slouken@2973
   818
        }
slouken@2973
   819
        IDirect3DTexture9_UnlockRect(data->texture, 0);
slouken@2973
   820
#endif // SDL_MEMORY_POOL_DEFAULT
slouken@2973
   821
slouken@2973
   822
        return 0;
slouken@1903
   823
    }
slouken@1895
   824
}
slouken@1895
   825
slouken@1895
   826
static int
slouken@1913
   827
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1913
   828
                const SDL_Rect * rect, int markDirty, void **pixels,
slouken@1913
   829
                int *pitch)
slouken@1895
   830
{
slouken@1913
   831
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1895
   832
slouken@2973
   833
    if (data->yuv) {
slouken@2973
   834
        return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
slouken@2973
   835
                                     pitch);
slouken@2973
   836
    } else {
slouken@2973
   837
        RECT d3drect;
slouken@2973
   838
        D3DLOCKED_RECT locked;
slouken@2973
   839
        HRESULT result;
slouken@1903
   840
slouken@2973
   841
        d3drect.left = rect->x;
slouken@2973
   842
        d3drect.right = rect->x + rect->w;
slouken@2973
   843
        d3drect.top = rect->y;
slouken@2973
   844
        d3drect.bottom = rect->y + rect->h;
slouken@2973
   845
slouken@2973
   846
        result =
slouken@2973
   847
            IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
slouken@2990
   848
                                       markDirty ? 0 :
slouken@2990
   849
                                       D3DLOCK_NO_DIRTY_UPDATE);
slouken@2973
   850
        if (FAILED(result)) {
slouken@2973
   851
            D3D_SetError("LockRect()", result);
slouken@2973
   852
            return -1;
slouken@2973
   853
        }
slouken@2973
   854
        *pixels = locked.pBits;
slouken@2973
   855
        *pitch = locked.Pitch;
slouken@2973
   856
        return 0;
slouken@1903
   857
    }
slouken@1895
   858
}
slouken@1895
   859
slouken@1895
   860
static void
slouken@1913
   861
D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
   862
{
slouken@1913
   863
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1895
   864
slouken@2973
   865
    if (data->yuv) {
slouken@2973
   866
        SDL_SW_UnlockYUVTexture(data->yuv);
slouken@2973
   867
        UpdateYUVTextureData(texture);
slouken@2973
   868
    } else {
slouken@2973
   869
        IDirect3DTexture9_UnlockRect(data->texture, 0);
slouken@2973
   870
    }
slouken@1895
   871
}
slouken@1895
   872
slouken@1895
   873
static void
slouken@1913
   874
D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
slouken@1913
   875
                 const SDL_Rect * rects)
slouken@1895
   876
{
slouken@1913
   877
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1903
   878
    RECT d3drect;
slouken@1903
   879
    int i;
slouken@1903
   880
slouken@1903
   881
    for (i = 0; i < numrects; ++i) {
slouken@1903
   882
        const SDL_Rect *rect = &rects[i];
slouken@1903
   883
slouken@1903
   884
        d3drect.left = rect->x;
slouken@1903
   885
        d3drect.right = rect->x + rect->w;
slouken@1903
   886
        d3drect.top = rect->y;
slouken@1903
   887
        d3drect.bottom = rect->y + rect->h;
slouken@1903
   888
slouken@1903
   889
        IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
slouken@1903
   890
    }
slouken@1895
   891
}
slouken@1895
   892
slouken@2932
   893
static void
slouken@2933
   894
D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
slouken@2932
   895
{
slouken@2932
   896
    switch (blendMode) {
slouken@2932
   897
    case SDL_BLENDMODE_NONE:
slouken@2932
   898
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
slouken@2932
   899
                                        FALSE);
slouken@2932
   900
        break;
slouken@2932
   901
    case SDL_BLENDMODE_MASK:
slouken@2932
   902
    case SDL_BLENDMODE_BLEND:
slouken@2932
   903
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
slouken@2932
   904
                                        TRUE);
slouken@2932
   905
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
slouken@2932
   906
                                        D3DBLEND_SRCALPHA);
slouken@2932
   907
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
slouken@2932
   908
                                        D3DBLEND_INVSRCALPHA);
slouken@2932
   909
        break;
slouken@2932
   910
    case SDL_BLENDMODE_ADD:
slouken@2932
   911
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
slouken@2932
   912
                                        TRUE);
slouken@2932
   913
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
slouken@2932
   914
                                        D3DBLEND_SRCALPHA);
slouken@2932
   915
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
slouken@2932
   916
                                        D3DBLEND_ONE);
slouken@2932
   917
        break;
slouken@2932
   918
    case SDL_BLENDMODE_MOD:
slouken@2932
   919
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
slouken@2932
   920
                                        TRUE);
slouken@2932
   921
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
slouken@2932
   922
                                        D3DBLEND_ZERO);
slouken@2932
   923
        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
slouken@2932
   924
                                        D3DBLEND_SRCCOLOR);
slouken@2932
   925
        break;
slouken@2932
   926
    }
slouken@2932
   927
}
slouken@2932
   928
slouken@1895
   929
static int
slouken@2932
   930
D3D_RenderPoint(SDL_Renderer * renderer, int x, int y)
slouken@1895
   931
{
slouken@1913
   932
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@2932
   933
    DWORD color;
slouken@2932
   934
    Vertex vertices[1];
slouken@1900
   935
    HRESULT result;
slouken@1895
   936
slouken@1900
   937
    if (data->beginScene) {
slouken@1900
   938
        IDirect3DDevice9_BeginScene(data->device);
slouken@1900
   939
        data->beginScene = SDL_FALSE;
slouken@1900
   940
    }
slouken@1895
   941
slouken@2932
   942
    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
slouken@1901
   943
slouken@3267
   944
    vertices[0].x = (float) x;
slouken@3267
   945
    vertices[0].y = (float) y;
slouken@2932
   946
    vertices[0].z = 0.0f;
slouken@2932
   947
    vertices[0].rhw = 1.0f;
slouken@2932
   948
    vertices[0].color = color;
slouken@2932
   949
    vertices[0].u = 0.0f;
slouken@2932
   950
    vertices[0].v = 0.0f;
slouken@2932
   951
slouken@2932
   952
    D3D_SetBlendMode(data, renderer->blendMode);
slouken@2932
   953
slouken@2933
   954
    result =
slouken@2933
   955
        IDirect3DDevice9_SetTexture(data->device, 0,
slouken@2933
   956
                                    (IDirect3DBaseTexture9 *) 0);
slouken@2932
   957
    if (FAILED(result)) {
slouken@2932
   958
        D3D_SetError("SetTexture()", result);
slouken@2932
   959
        return -1;
slouken@2932
   960
    }
slouken@1903
   961
    result =
slouken@2932
   962
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1,
slouken@2932
   963
                                         vertices, sizeof(*vertices));
slouken@1900
   964
    if (FAILED(result)) {
slouken@2932
   965
        D3D_SetError("DrawPrimitiveUP()", result);
slouken@2932
   966
        return -1;
slouken@2932
   967
    }
slouken@2932
   968
    return 0;
slouken@2932
   969
}
slouken@2932
   970
slouken@2932
   971
static int
slouken@2932
   972
D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
slouken@2932
   973
{
slouken@2932
   974
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@2932
   975
    DWORD color;
slouken@2932
   976
    Vertex vertices[2];
slouken@2932
   977
    HRESULT result;
slouken@2932
   978
slouken@2932
   979
    if (data->beginScene) {
slouken@2932
   980
        IDirect3DDevice9_BeginScene(data->device);
slouken@2932
   981
        data->beginScene = SDL_FALSE;
slouken@2932
   982
    }
slouken@2932
   983
slouken@2932
   984
    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
slouken@2932
   985
slouken@3267
   986
    vertices[0].x = (float) x1;
slouken@3267
   987
    vertices[0].y = (float) y1;
slouken@2932
   988
    vertices[0].z = 0.0f;
slouken@2932
   989
    vertices[0].rhw = 1.0f;
slouken@2932
   990
    vertices[0].color = color;
slouken@2932
   991
    vertices[0].u = 0.0f;
slouken@2932
   992
    vertices[0].v = 0.0f;
slouken@2932
   993
slouken@3267
   994
    vertices[1].x = (float) x2;
slouken@3267
   995
    vertices[1].y = (float) y2;
slouken@2932
   996
    vertices[1].z = 0.0f;
slouken@2932
   997
    vertices[1].rhw = 1.0f;
slouken@2932
   998
    vertices[1].color = color;
slouken@2932
   999
    vertices[1].u = 0.0f;
slouken@2932
  1000
    vertices[1].v = 0.0f;
slouken@2932
  1001
slouken@2932
  1002
    D3D_SetBlendMode(data, renderer->blendMode);
slouken@2932
  1003
slouken@2933
  1004
    result =
slouken@2933
  1005
        IDirect3DDevice9_SetTexture(data->device, 0,
slouken@2933
  1006
                                    (IDirect3DBaseTexture9 *) 0);
slouken@2932
  1007
    if (FAILED(result)) {
slouken@2932
  1008
        D3D_SetError("SetTexture()", result);
slouken@2932
  1009
        return -1;
slouken@2932
  1010
    }
slouken@2932
  1011
    result =
slouken@2932
  1012
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINELIST, 1,
slouken@2932
  1013
                                         vertices, sizeof(*vertices));
slouken@2932
  1014
    if (FAILED(result)) {
slouken@2932
  1015
        D3D_SetError("DrawPrimitiveUP()", result);
slouken@2932
  1016
        return -1;
slouken@2932
  1017
    }
slouken@2932
  1018
    return 0;
slouken@2932
  1019
}
slouken@2932
  1020
slouken@2932
  1021
static int
slouken@2932
  1022
D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
slouken@2932
  1023
{
slouken@2932
  1024
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@2932
  1025
    float minx, miny, maxx, maxy;
slouken@2932
  1026
    DWORD color;
slouken@2932
  1027
    Vertex vertices[4];
slouken@2932
  1028
    HRESULT result;
slouken@2932
  1029
slouken@2932
  1030
    if (data->beginScene) {
slouken@2932
  1031
        IDirect3DDevice9_BeginScene(data->device);
slouken@2932
  1032
        data->beginScene = SDL_FALSE;
slouken@2932
  1033
    }
slouken@2932
  1034
slouken@3267
  1035
    minx = (float) rect->x;
slouken@3267
  1036
    miny = (float) rect->y;
slouken@3267
  1037
    maxx = (float) rect->x + rect->w;
slouken@3267
  1038
    maxy = (float) rect->y + rect->h;
slouken@2932
  1039
slouken@2932
  1040
    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
slouken@2932
  1041
slouken@2932
  1042
    vertices[0].x = minx;
slouken@2932
  1043
    vertices[0].y = miny;
slouken@2932
  1044
    vertices[0].z = 0.0f;
slouken@2932
  1045
    vertices[0].rhw = 1.0f;
slouken@2932
  1046
    vertices[0].color = color;
slouken@2932
  1047
    vertices[0].u = 0.0f;
slouken@2932
  1048
    vertices[0].v = 0.0f;
slouken@2932
  1049
slouken@2932
  1050
    vertices[1].x = maxx;
slouken@2932
  1051
    vertices[1].y = miny;
slouken@2932
  1052
    vertices[1].z = 0.0f;
slouken@2932
  1053
    vertices[1].rhw = 1.0f;
slouken@2932
  1054
    vertices[1].color = color;
slouken@2932
  1055
    vertices[1].u = 0.0f;
slouken@2932
  1056
    vertices[1].v = 0.0f;
slouken@2932
  1057
slouken@2932
  1058
    vertices[2].x = maxx;
slouken@2932
  1059
    vertices[2].y = maxy;
slouken@2932
  1060
    vertices[2].z = 0.0f;
slouken@2932
  1061
    vertices[2].rhw = 1.0f;
slouken@2932
  1062
    vertices[2].color = color;
slouken@2932
  1063
    vertices[2].u = 0.0f;
slouken@2932
  1064
    vertices[2].v = 0.0f;
slouken@2932
  1065
slouken@2932
  1066
    vertices[3].x = minx;
slouken@2932
  1067
    vertices[3].y = maxy;
slouken@2932
  1068
    vertices[3].z = 0.0f;
slouken@2932
  1069
    vertices[3].rhw = 1.0f;
slouken@2932
  1070
    vertices[3].color = color;
slouken@2932
  1071
    vertices[3].u = 0.0f;
slouken@2932
  1072
    vertices[3].v = 0.0f;
slouken@2932
  1073
slouken@2932
  1074
    D3D_SetBlendMode(data, renderer->blendMode);
slouken@2932
  1075
slouken@2933
  1076
    result =
slouken@2933
  1077
        IDirect3DDevice9_SetTexture(data->device, 0,
slouken@2933
  1078
                                    (IDirect3DBaseTexture9 *) 0);
slouken@2932
  1079
    if (FAILED(result)) {
slouken@2932
  1080
        D3D_SetError("SetTexture()", result);
slouken@2932
  1081
        return -1;
slouken@2932
  1082
    }
slouken@2932
  1083
    result =
slouken@2932
  1084
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
slouken@2932
  1085
                                         vertices, sizeof(*vertices));
slouken@2932
  1086
    if (FAILED(result)) {
slouken@2932
  1087
        D3D_SetError("DrawPrimitiveUP()", result);
slouken@1900
  1088
        return -1;
slouken@1900
  1089
    }
slouken@1895
  1090
    return 0;
slouken@1895
  1091
}
slouken@1895
  1092
slouken@1895
  1093
static int
slouken@1913
  1094
D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
  1095
               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
slouken@1895
  1096
{
slouken@1913
  1097
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@1913
  1098
    D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
slouken@1903
  1099
    float minx, miny, maxx, maxy;
slouken@1904
  1100
    float minu, maxu, minv, maxv;
slouken@1987
  1101
    DWORD color;
slouken@1903
  1102
    Vertex vertices[4];
slouken@1903
  1103
    HRESULT result;
slouken@1895
  1104
slouken@1900
  1105
    if (data->beginScene) {
slouken@1900
  1106
        IDirect3DDevice9_BeginScene(data->device);
slouken@1900
  1107
        data->beginScene = SDL_FALSE;
slouken@1900
  1108
    }
slouken@1903
  1109
slouken@3279
  1110
    minx = (float) dstrect->x - 0.5f;
slouken@3279
  1111
    miny = (float) dstrect->y - 0.5f;
slouken@3279
  1112
    maxx = (float) dstrect->x + dstrect->w - 0.5f;
slouken@3279
  1113
    maxy = (float) dstrect->y + dstrect->h - 0.5f;
slouken@1903
  1114
slouken@1904
  1115
    minu = (float) srcrect->x / texture->w;
slouken@1904
  1116
    maxu = (float) (srcrect->x + srcrect->w) / texture->w;
slouken@1904
  1117
    minv = (float) srcrect->y / texture->h;
slouken@1904
  1118
    maxv = (float) (srcrect->y + srcrect->h) / texture->h;
slouken@1903
  1119
slouken@1987
  1120
    color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b);
slouken@1987
  1121
slouken@1903
  1122
    vertices[0].x = minx;
slouken@1903
  1123
    vertices[0].y = miny;
slouken@1903
  1124
    vertices[0].z = 0.0f;
slouken@1904
  1125
    vertices[0].rhw = 1.0f;
slouken@1987
  1126
    vertices[0].color = color;
slouken@1904
  1127
    vertices[0].u = minu;
slouken@1904
  1128
    vertices[0].v = minv;
slouken@1904
  1129
slouken@1903
  1130
    vertices[1].x = maxx;
slouken@1903
  1131
    vertices[1].y = miny;
slouken@1903
  1132
    vertices[1].z = 0.0f;
slouken@1904
  1133
    vertices[1].rhw = 1.0f;
slouken@1987
  1134
    vertices[1].color = color;
slouken@1904
  1135
    vertices[1].u = maxu;
slouken@1904
  1136
    vertices[1].v = minv;
slouken@1904
  1137
slouken@1903
  1138
    vertices[2].x = maxx;
slouken@1903
  1139
    vertices[2].y = maxy;
slouken@1903
  1140
    vertices[2].z = 0.0f;
slouken@1904
  1141
    vertices[2].rhw = 1.0f;
slouken@1987
  1142
    vertices[2].color = color;
slouken@1904
  1143
    vertices[2].u = maxu;
slouken@1904
  1144
    vertices[2].v = maxv;
slouken@1904
  1145
slouken@1903
  1146
    vertices[3].x = minx;
slouken@1903
  1147
    vertices[3].y = maxy;
slouken@1903
  1148
    vertices[3].z = 0.0f;
slouken@1904
  1149
    vertices[3].rhw = 1.0f;
slouken@1987
  1150
    vertices[3].color = color;
slouken@1904
  1151
    vertices[3].u = minu;
slouken@1904
  1152
    vertices[3].v = maxv;
slouken@1903
  1153
slouken@2932
  1154
    D3D_SetBlendMode(data, texture->blendMode);
slouken@1916
  1155
slouken@1985
  1156
    switch (texture->scaleMode) {
slouken@1965
  1157
    case SDL_TEXTURESCALEMODE_NONE:
slouken@1965
  1158
    case SDL_TEXTURESCALEMODE_FAST:
slouken@1917
  1159
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
slouken@1917
  1160
                                         D3DTEXF_POINT);
slouken@1917
  1161
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
slouken@1917
  1162
                                         D3DTEXF_POINT);
slouken@1917
  1163
        break;
slouken@1965
  1164
    case SDL_TEXTURESCALEMODE_SLOW:
slouken@1917
  1165
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
slouken@1917
  1166
                                         D3DTEXF_LINEAR);
slouken@1917
  1167
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
slouken@1917
  1168
                                         D3DTEXF_LINEAR);
slouken@1917
  1169
        break;
slouken@1965
  1170
    case SDL_TEXTURESCALEMODE_BEST:
slouken@1917
  1171
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
slouken@1917
  1172
                                         D3DTEXF_GAUSSIANQUAD);
slouken@1917
  1173
        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
slouken@1917
  1174
                                         D3DTEXF_GAUSSIANQUAD);
slouken@1917
  1175
        break;
slouken@1917
  1176
    }
slouken@1917
  1177
slouken@1903
  1178
    result =
slouken@2735
  1179
        IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
slouken@2735
  1180
                                    texturedata->texture);
slouken@1903
  1181
    if (FAILED(result)) {
slouken@1903
  1182
        D3D_SetError("SetTexture()", result);
slouken@1903
  1183
        return -1;
slouken@1903
  1184
    }
slouken@1903
  1185
    result =
slouken@1903
  1186
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
slouken@1903
  1187
                                         vertices, sizeof(*vertices));
slouken@1903
  1188
    if (FAILED(result)) {
slouken@1903
  1189
        D3D_SetError("DrawPrimitiveUP()", result);
slouken@1903
  1190
        return -1;
slouken@1903
  1191
    }
slouken@1895
  1192
    return 0;
slouken@1895
  1193
}
slouken@1895
  1194
slouken@3427
  1195
static int
slouken@3427
  1196
D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3480
  1197
                     Uint32 format, void * pixels, int pitch)
slouken@3427
  1198
{
slouken@3427
  1199
    BYTE * pBytes;
slouken@3427
  1200
    D3DLOCKED_RECT lockedRect;
slouken@3427
  1201
    BYTE b, g, r, a;
slouken@3427
  1202
    unsigned long index;
slouken@3427
  1203
    int cur_mouse;
slouken@3427
  1204
    int x, y;
slouken@3427
  1205
slouken@3427
  1206
    LPDIRECT3DSURFACE9 backBuffer;
slouken@3427
  1207
    LPDIRECT3DSURFACE9 pickOffscreenSurface;
slouken@3427
  1208
    D3DSURFACE_DESC desc;
slouken@3427
  1209
slouken@3427
  1210
    D3D_RenderData * data = (D3D_RenderData *) renderer->driverdata;
slouken@3427
  1211
    
slouken@3427
  1212
    IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
slouken@3427
  1213
    
slouken@3427
  1214
    
slouken@3427
  1215
    IDirect3DSurface9_GetDesc(backBuffer, &desc);
slouken@3427
  1216
slouken@3427
  1217
    IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pickOffscreenSurface, NULL);
slouken@3427
  1218
slouken@3427
  1219
    IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, pickOffscreenSurface);
slouken@3427
  1220
slouken@3427
  1221
    IDirect3DSurface9_LockRect(pickOffscreenSurface, &lockedRect, NULL, D3DLOCK_READONLY);
slouken@3427
  1222
    pBytes = (BYTE*)lockedRect.pBits;
slouken@3427
  1223
    IDirect3DSurface9_UnlockRect(pickOffscreenSurface);
slouken@3427
  1224
slouken@3427
  1225
    // just to debug -->
slouken@3427
  1226
    cur_mouse = SDL_SelectMouse(-1);
slouken@3427
  1227
    SDL_GetMouseState(cur_mouse, &x, &y);
slouken@3427
  1228
    index = (x * 4 + (y * lockedRect.Pitch));
slouken@3427
  1229
slouken@3427
  1230
    b = pBytes[index];
slouken@3427
  1231
    g = pBytes[index+1];
slouken@3427
  1232
    r = pBytes[index+2];
slouken@3427
  1233
    a = pBytes[index+3];
slouken@3427
  1234
    // <--
slouken@3427
  1235
    
slouken@3427
  1236
    return -1;
slouken@3427
  1237
}
slouken@3427
  1238
slouken@3480
  1239
static int
slouken@3480
  1240
D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3480
  1241
                      Uint32 format, const void * pixels, int pitch)
slouken@3480
  1242
{
slouken@3480
  1243
    /* Work in progress */
slouken@3480
  1244
    return -1;
slouken@3480
  1245
}
slouken@3480
  1246
slouken@1895
  1247
static void
slouken@1913
  1248
D3D_RenderPresent(SDL_Renderer * renderer)
slouken@1895
  1249
{
slouken@1913
  1250
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@1900
  1251
    HRESULT result;
slouken@1900
  1252
slouken@1900
  1253
    if (!data->beginScene) {
slouken@1900
  1254
        IDirect3DDevice9_EndScene(data->device);
slouken@1900
  1255
        data->beginScene = SDL_TRUE;
slouken@1900
  1256
    }
slouken@1900
  1257
slouken@1975
  1258
    result = IDirect3DDevice9_TestCooperativeLevel(data->device);
slouken@1975
  1259
    if (result == D3DERR_DEVICELOST) {
slouken@1975
  1260
        /* We'll reset later */
slouken@1975
  1261
        return;
slouken@1975
  1262
    }
slouken@1975
  1263
    if (result == D3DERR_DEVICENOTRESET) {
slouken@1975
  1264
        D3D_Reset(renderer);
slouken@1975
  1265
    }
slouken@1900
  1266
    result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
slouken@1900
  1267
    if (FAILED(result)) {
slouken@1900
  1268
        D3D_SetError("Present()", result);
slouken@1900
  1269
    }
slouken@1895
  1270
}
slouken@1895
  1271
slouken@1895
  1272
static void
slouken@1913
  1273
D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
  1274
{
slouken@1913
  1275
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
slouken@1895
  1276
slouken@1895
  1277
    if (!data) {
slouken@1895
  1278
        return;
slouken@1895
  1279
    }
slouken@2973
  1280
    if (data->yuv) {
slouken@2973
  1281
        SDL_SW_DestroyYUVTexture(data->yuv);
slouken@2973
  1282
    }
slouken@1903
  1283
    if (data->texture) {
slouken@1903
  1284
        IDirect3DTexture9_Release(data->texture);
slouken@1903
  1285
    }
slouken@1895
  1286
    SDL_free(data);
slouken@1895
  1287
    texture->driverdata = NULL;
slouken@1895
  1288
}
slouken@1895
  1289
slouken@1975
  1290
static void
slouken@1913
  1291
D3D_DestroyRenderer(SDL_Renderer * renderer)
slouken@1895
  1292
{
slouken@1913
  1293
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
slouken@1895
  1294
slouken@1895
  1295
    if (data) {
slouken@1900
  1296
        if (data->device) {
slouken@1900
  1297
            IDirect3DDevice9_Release(data->device);
slouken@1900
  1298
        }
slouken@1895
  1299
        SDL_free(data);
slouken@1895
  1300
    }
slouken@1895
  1301
    SDL_free(renderer);
slouken@1895
  1302
}
slouken@1895
  1303
slouken@1895
  1304
#endif /* SDL_VIDEO_RENDER_D3D */
slouken@1895
  1305
slouken@1895
  1306
/* vi: set ts=4 sw=4 expandtab: */