src/video/win32/SDL_d3drender.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Jul 2006 06:40:53 +0000
changeset 1903 f132024010be
parent 1901 f1828a500391
child 1904 1a713f9d1f71
permissions -rw-r--r--
More of the Direct3D renderer is implemented, I'm not sure why it's not showing texture copies yet...
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #if SDL_VIDEO_RENDER_D3D
    25 
    26 #include "SDL_win32video.h"
    27 
    28 /* Direct3D renderer implementation */
    29 
    30 static SDL_Renderer *SDL_D3D_CreateRenderer(SDL_Window * window,
    31                                             Uint32 flags);
    32 static int SDL_D3D_CreateTexture(SDL_Renderer * renderer,
    33                                  SDL_Texture * texture);
    34 static int SDL_D3D_SetTexturePalette(SDL_Renderer * renderer,
    35                                      SDL_Texture * texture,
    36                                      const SDL_Color * colors, int firstcolor,
    37                                      int ncolors);
    38 static int SDL_D3D_GetTexturePalette(SDL_Renderer * renderer,
    39                                      SDL_Texture * texture,
    40                                      SDL_Color * colors, int firstcolor,
    41                                      int ncolors);
    42 static int SDL_D3D_UpdateTexture(SDL_Renderer * renderer,
    43                                  SDL_Texture * texture, const SDL_Rect * rect,
    44                                  const void *pixels, int pitch);
    45 static int SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    46                                const SDL_Rect * rect, int markDirty,
    47                                void **pixels, int *pitch);
    48 static void SDL_D3D_UnlockTexture(SDL_Renderer * renderer,
    49                                   SDL_Texture * texture);
    50 static void SDL_D3D_DirtyTexture(SDL_Renderer * renderer,
    51                                  SDL_Texture * texture, int numrects,
    52                                  const SDL_Rect * rects);
    53 static void SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer,
    54                                         SDL_Texture * texture);
    55 static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
    56                               Uint32 color);
    57 static int SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    58                               const SDL_Rect * srcrect,
    59                               const SDL_Rect * dstrect, int blendMode,
    60                               int scaleMode);
    61 static int SDL_D3D_RenderReadPixels(SDL_Renderer * renderer,
    62                                     const SDL_Rect * rect, void *pixels,
    63                                     int pitch);
    64 static int SDL_D3D_RenderWritePixels(SDL_Renderer * renderer,
    65                                      const SDL_Rect * rect,
    66                                      const void *pixels, int pitch);
    67 static void SDL_D3D_RenderPresent(SDL_Renderer * renderer);
    68 static void SDL_D3D_DestroyTexture(SDL_Renderer * renderer,
    69                                    SDL_Texture * texture);
    70 static void SDL_D3D_DestroyRenderer(SDL_Renderer * renderer);
    71 
    72 
    73 SDL_RenderDriver SDL_D3D_RenderDriver = {
    74     SDL_D3D_CreateRenderer,
    75     {
    76      "d3d",
    77      (                          //SDL_Renderer_Minimal |
    78          SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
    79          SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
    80          SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
    81      (SDL_TextureBlendMode_None |
    82       SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
    83      (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
    84      12,
    85      {
    86       SDL_PixelFormat_Index8,
    87       SDL_PixelFormat_RGB332,
    88       SDL_PixelFormat_RGB444,
    89       SDL_PixelFormat_RGB555,
    90       SDL_PixelFormat_ARGB4444,
    91       SDL_PixelFormat_ARGB1555,
    92       SDL_PixelFormat_RGB565,
    93       SDL_PixelFormat_RGB888,
    94       SDL_PixelFormat_ARGB8888,
    95       SDL_PixelFormat_ARGB2101010,
    96       SDL_PixelFormat_UYVY,
    97       SDL_PixelFormat_YUY2},
    98      0,
    99      0}
   100 };
   101 
   102 typedef struct
   103 {
   104     IDirect3DDevice9 *device;
   105     SDL_bool beginScene;
   106 } SDL_D3D_RenderData;
   107 
   108 typedef struct
   109 {
   110     IDirect3DTexture9 *texture;
   111 } SDL_D3D_TextureData;
   112 
   113 typedef struct
   114 {
   115     float x, y, z;
   116     float tu, tv;
   117 } Vertex;
   118 
   119 static void
   120 D3D_SetError(const char *prefix, HRESULT result)
   121 {
   122     const char *error;
   123 
   124     switch (result) {
   125     case D3DERR_WRONGTEXTUREFORMAT:
   126         error = "WRONGTEXTUREFORMAT";
   127         break;
   128     case D3DERR_UNSUPPORTEDCOLOROPERATION:
   129         error = "UNSUPPORTEDCOLOROPERATION";
   130         break;
   131     case D3DERR_UNSUPPORTEDCOLORARG:
   132         error = "UNSUPPORTEDCOLORARG";
   133         break;
   134     case D3DERR_UNSUPPORTEDALPHAOPERATION:
   135         error = "UNSUPPORTEDALPHAOPERATION";
   136         break;
   137     case D3DERR_UNSUPPORTEDALPHAARG:
   138         error = "UNSUPPORTEDALPHAARG";
   139         break;
   140     case D3DERR_TOOMANYOPERATIONS:
   141         error = "TOOMANYOPERATIONS";
   142         break;
   143     case D3DERR_CONFLICTINGTEXTUREFILTER:
   144         error = "CONFLICTINGTEXTUREFILTER";
   145         break;
   146     case D3DERR_UNSUPPORTEDFACTORVALUE:
   147         error = "UNSUPPORTEDFACTORVALUE";
   148         break;
   149     case D3DERR_CONFLICTINGRENDERSTATE:
   150         error = "CONFLICTINGRENDERSTATE";
   151         break;
   152     case D3DERR_UNSUPPORTEDTEXTUREFILTER:
   153         error = "UNSUPPORTEDTEXTUREFILTER";
   154         break;
   155     case D3DERR_CONFLICTINGTEXTUREPALETTE:
   156         error = "CONFLICTINGTEXTUREPALETTE";
   157         break;
   158     case D3DERR_DRIVERINTERNALERROR:
   159         error = "DRIVERINTERNALERROR";
   160         break;
   161     case D3DERR_NOTFOUND:
   162         error = "NOTFOUND";
   163         break;
   164     case D3DERR_MOREDATA:
   165         error = "MOREDATA";
   166         break;
   167     case D3DERR_DEVICELOST:
   168         error = "DEVICELOST";
   169         break;
   170     case D3DERR_DEVICENOTRESET:
   171         error = "DEVICENOTRESET";
   172         break;
   173     case D3DERR_NOTAVAILABLE:
   174         error = "NOTAVAILABLE";
   175         break;
   176     case D3DERR_OUTOFVIDEOMEMORY:
   177         error = "OUTOFVIDEOMEMORY";
   178         break;
   179     case D3DERR_INVALIDDEVICE:
   180         error = "INVALIDDEVICE";
   181         break;
   182     case D3DERR_INVALIDCALL:
   183         error = "INVALIDCALL";
   184         break;
   185     case D3DERR_DRIVERINVALIDCALL:
   186         error = "DRIVERINVALIDCALL";
   187         break;
   188     case D3DERR_WASSTILLDRAWING:
   189         error = "WASSTILLDRAWING";
   190         break;
   191     default:
   192         error = "UNKNOWN";
   193         break;
   194     }
   195     SDL_SetError("%s: %s", prefix, error);
   196 }
   197 
   198 static D3DFORMAT
   199 PixelFormatToD3DFMT(Uint32 format)
   200 {
   201     switch (format) {
   202     case SDL_PixelFormat_Index8:
   203         return D3DFMT_P8;
   204     case SDL_PixelFormat_RGB332:
   205         return D3DFMT_R3G3B2;
   206     case SDL_PixelFormat_RGB444:
   207         return D3DFMT_X4R4G4B4;
   208     case SDL_PixelFormat_RGB555:
   209         return D3DFMT_X1R5G5B5;
   210     case SDL_PixelFormat_ARGB4444:
   211         return D3DFMT_A4R4G4B4;
   212     case SDL_PixelFormat_ARGB1555:
   213         return D3DFMT_A1R5G5B5;
   214     case SDL_PixelFormat_RGB565:
   215         return D3DFMT_R5G6B5;
   216     case SDL_PixelFormat_RGB888:
   217         return D3DFMT_X8R8G8B8;
   218     case SDL_PixelFormat_ARGB8888:
   219         return D3DFMT_A8R8G8B8;
   220     case SDL_PixelFormat_ARGB2101010:
   221         return D3DFMT_A2R10G10B10;
   222     case SDL_PixelFormat_UYVY:
   223         return D3DFMT_UYVY;
   224     case SDL_PixelFormat_YUY2:
   225         return D3DFMT_YUY2;
   226     default:
   227         return D3DFMT_UNKNOWN;
   228     }
   229 }
   230 
   231 void
   232 D3D_AddRenderDriver(_THIS)
   233 {
   234     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   235 
   236     if (data->d3d) {
   237         SDL_AddRenderDriver(0, &SDL_D3D_RenderDriver);
   238     }
   239 }
   240 
   241 SDL_Renderer *
   242 SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
   243 {
   244     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   245     SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
   246     SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
   247     SDL_Renderer *renderer;
   248     SDL_D3D_RenderData *data;
   249     HRESULT result;
   250     D3DPRESENT_PARAMETERS pparams;
   251 
   252     renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
   253     if (!renderer) {
   254         SDL_OutOfMemory();
   255         return NULL;
   256     }
   257     SDL_zerop(renderer);
   258 
   259     data = (SDL_D3D_RenderData *) SDL_malloc(sizeof(*data));
   260     if (!data) {
   261         SDL_D3D_DestroyRenderer(renderer);
   262         SDL_OutOfMemory();
   263         return NULL;
   264     }
   265     SDL_zerop(data);
   266 
   267     renderer->CreateTexture = SDL_D3D_CreateTexture;
   268     renderer->SetTexturePalette = SDL_D3D_SetTexturePalette;
   269     renderer->GetTexturePalette = SDL_D3D_GetTexturePalette;
   270     renderer->UpdateTexture = SDL_D3D_UpdateTexture;
   271     renderer->LockTexture = SDL_D3D_LockTexture;
   272     renderer->UnlockTexture = SDL_D3D_UnlockTexture;
   273     renderer->DirtyTexture = SDL_D3D_DirtyTexture;
   274     renderer->SelectRenderTexture = SDL_D3D_SelectRenderTexture;
   275     renderer->RenderFill = SDL_D3D_RenderFill;
   276     renderer->RenderCopy = SDL_D3D_RenderCopy;
   277     renderer->RenderReadPixels = SDL_D3D_RenderReadPixels;
   278     renderer->RenderWritePixels = SDL_D3D_RenderWritePixels;
   279     renderer->RenderPresent = SDL_D3D_RenderPresent;
   280     renderer->DestroyTexture = SDL_D3D_DestroyTexture;
   281     renderer->DestroyRenderer = SDL_D3D_DestroyRenderer;
   282     renderer->info = SDL_D3D_RenderDriver.info;
   283     renderer->window = window->id;
   284     renderer->driverdata = data;
   285 
   286     renderer->info.flags = SDL_Renderer_RenderTarget;
   287 
   288     SDL_zero(pparams);
   289     pparams.BackBufferWidth = window->w;
   290     pparams.BackBufferHeight = window->h;
   291     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   292         pparams.BackBufferFormat =
   293             PixelFormatToD3DFMT(display->fullscreen_mode->format);
   294     } else {
   295         pparams.BackBufferFormat = D3DFMT_UNKNOWN;
   296     }
   297     if (flags & SDL_Renderer_PresentFlip2) {
   298         pparams.BackBufferCount = 2;
   299         pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
   300     } else if (flags & SDL_Renderer_PresentFlip3) {
   301         pparams.BackBufferCount = 3;
   302         pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
   303     } else if (flags & SDL_Renderer_PresentCopy) {
   304         pparams.BackBufferCount = 1;
   305         pparams.SwapEffect = D3DSWAPEFFECT_COPY;
   306     } else {
   307         pparams.BackBufferCount = 1;
   308         pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
   309     }
   310     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   311         pparams.Windowed = FALSE;
   312         pparams.FullScreen_RefreshRateInHz =
   313             display->fullscreen_mode->refresh_rate;
   314     } else {
   315         pparams.Windowed = TRUE;
   316         pparams.FullScreen_RefreshRateInHz = 0;
   317     }
   318     pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
   319 
   320     result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT,        /* FIXME */
   321                                      D3DDEVTYPE_HAL,
   322                                      windowdata->hwnd,
   323                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
   324                                      &pparams, &data->device);
   325     if (FAILED(result)) {
   326         SDL_D3D_DestroyRenderer(renderer);
   327         D3D_SetError("CreateDevice()", result);
   328         return NULL;
   329     }
   330     data->beginScene = SDL_TRUE;
   331 
   332     /* Set up parameters for rendering */
   333     IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
   334                                     D3DCULL_NONE);
   335     IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZ | D3DFVF_TEX1);
   336 
   337     return renderer;
   338 }
   339 
   340 static int
   341 SDL_D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   342 {
   343     SDL_D3D_RenderData *renderdata =
   344         (SDL_D3D_RenderData *) renderer->driverdata;
   345     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   346     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   347     SDL_D3D_TextureData *data;
   348     D3DPOOL pool;
   349     HRESULT result;
   350 
   351     data = (SDL_D3D_TextureData *) SDL_malloc(sizeof(*data));
   352     if (!data) {
   353         SDL_OutOfMemory();
   354         return -1;
   355     }
   356     SDL_zerop(data);
   357 
   358     texture->driverdata = data;
   359 
   360     if (texture->access == SDL_TextureAccess_Local) {
   361         pool = D3DPOOL_MANAGED;
   362     } else {
   363         pool = D3DPOOL_DEFAULT;
   364     }
   365     result =
   366         IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
   367                                        texture->h, 1, 0,
   368                                        PixelFormatToD3DFMT(texture->format),
   369                                        pool, &data->texture, NULL);
   370     if (FAILED(result)) {
   371         SDL_free(data);
   372         D3D_SetError("CreateTexture()", result);
   373         return -1;
   374     }
   375 
   376     return 0;
   377 }
   378 
   379 static int
   380 SDL_D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
   381                           const SDL_Color * colors, int firstcolor,
   382                           int ncolors)
   383 {
   384     SDL_D3D_RenderData *renderdata =
   385         (SDL_D3D_RenderData *) renderer->driverdata;
   386     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   387 
   388     return 0;
   389 }
   390 
   391 static int
   392 SDL_D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
   393                           SDL_Color * colors, int firstcolor, int ncolors)
   394 {
   395     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   396 
   397     return 0;
   398 }
   399 
   400 static int
   401 SDL_D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   402                       const SDL_Rect * rect, const void *pixels, int pitch)
   403 {
   404     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   405     SDL_D3D_RenderData *renderdata =
   406         (SDL_D3D_RenderData *) renderer->driverdata;
   407     IDirect3DTexture9 *temp;
   408     RECT d3drect;
   409     D3DLOCKED_RECT locked;
   410     const Uint8 *src;
   411     Uint8 *dst;
   412     int row, length;
   413     HRESULT result;
   414 
   415     result =
   416         IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
   417                                        texture->h, 1, 0,
   418                                        PixelFormatToD3DFMT(texture->format),
   419                                        D3DPOOL_SYSTEMMEM, &temp, NULL);
   420     if (FAILED(result)) {
   421         D3D_SetError("CreateTexture()", result);
   422         return -1;
   423     }
   424 
   425     d3drect.left = rect->x;
   426     d3drect.right = rect->x + rect->w;
   427     d3drect.top = rect->y;
   428     d3drect.bottom = rect->y + rect->h;
   429 
   430     result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
   431     if (FAILED(result)) {
   432         IDirect3DTexture9_Release(temp);
   433         D3D_SetError("LockRect()", result);
   434         return -1;
   435     }
   436 
   437     src = pixels;
   438     dst = locked.pBits;
   439     length = rect->w * SDL_BYTESPERPIXEL(texture->format);
   440     for (row = 0; row < rect->h; ++row) {
   441         SDL_memcpy(dst, src, length);
   442         src += pitch;
   443         dst += locked.Pitch;
   444     }
   445     IDirect3DTexture9_UnlockRect(temp, 0);
   446 
   447     result =
   448         IDirect3DDevice9_UpdateTexture(renderdata->device,
   449                                        (IDirect3DBaseTexture9 *) temp,
   450                                        (IDirect3DBaseTexture9 *) data->
   451                                        texture);
   452     IDirect3DTexture9_Release(temp);
   453     if (FAILED(result)) {
   454         D3D_SetError("UpdateTexture()", result);
   455         return -1;
   456     }
   457     return 0;
   458 }
   459 
   460 static int
   461 SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   462                     const SDL_Rect * rect, int markDirty, void **pixels,
   463                     int *pitch)
   464 {
   465     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   466     RECT d3drect;
   467     D3DLOCKED_RECT locked;
   468     HRESULT result;
   469 
   470     if (texture->access != SDL_TextureAccess_Local) {
   471         SDL_SetError("Can't lock remote video memory");
   472         return -1;
   473     }
   474 
   475     d3drect.left = rect->x;
   476     d3drect.right = rect->x + rect->w;
   477     d3drect.top = rect->y;
   478     d3drect.bottom = rect->y + rect->h;
   479 
   480     result =
   481         IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
   482                                    markDirty ? 0 : D3DLOCK_NO_DIRTY_UPDATE);
   483     if (FAILED(result)) {
   484         D3D_SetError("LockRect()", result);
   485         return -1;
   486     }
   487     *pixels = locked.pBits;
   488     *pitch = locked.Pitch;
   489     return 0;
   490 }
   491 
   492 static void
   493 SDL_D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   494 {
   495     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   496 
   497     IDirect3DTexture9_UnlockRect(data->texture, 0);
   498 }
   499 
   500 static void
   501 SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   502                      int numrects, const SDL_Rect * rects)
   503 {
   504     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   505     RECT d3drect;
   506     int i;
   507 
   508     for (i = 0; i < numrects; ++i) {
   509         const SDL_Rect *rect = &rects[i];
   510 
   511         d3drect.left = rect->x;
   512         d3drect.right = rect->x + rect->w;
   513         d3drect.top = rect->y;
   514         d3drect.bottom = rect->y + rect->h;
   515 
   516         IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
   517     }
   518 }
   519 
   520 static void
   521 SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   522 {
   523     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   524 }
   525 
   526 static int
   527 SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
   528                    Uint32 color)
   529 {
   530     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   531     D3DRECT d3drect;
   532     HRESULT result;
   533 
   534     if (data->beginScene) {
   535         IDirect3DDevice9_BeginScene(data->device);
   536         data->beginScene = SDL_FALSE;
   537     }
   538 
   539     d3drect.x1 = rect->x;
   540     d3drect.x2 = rect->x + rect->w;
   541     d3drect.y1 = rect->y;
   542     d3drect.y2 = rect->y + rect->h;
   543 
   544     result =
   545         IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET,
   546                                (D3DCOLOR) color, 1.0f, 0);
   547     if (FAILED(result)) {
   548         D3D_SetError("Clear()", result);
   549         return -1;
   550     }
   551     return 0;
   552 }
   553 
   554 static int
   555 SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   556                    const SDL_Rect * srcrect, const SDL_Rect * dstrect,
   557                    int blendMode, int scaleMode)
   558 {
   559     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   560     SDL_D3D_TextureData *texturedata =
   561         (SDL_D3D_TextureData *) texture->driverdata;
   562     float minx, miny, maxx, maxy;
   563     float mintu, maxtu, mintv, maxtv;
   564     Vertex vertices[4];
   565     HRESULT result;
   566 
   567     if (data->beginScene) {
   568         IDirect3DDevice9_BeginScene(data->device);
   569         data->beginScene = SDL_FALSE;
   570     }
   571 
   572     minx = (float) dstrect->x;
   573     miny = (float) dstrect->y;
   574     maxx = (float) dstrect->x + dstrect->w;
   575     maxy = (float) dstrect->y + dstrect->h;
   576 
   577     mintu = (float) srcrect->x / texture->w;
   578     maxtu = (float) (srcrect->x + srcrect->w) / texture->w;
   579     mintv = (float) srcrect->y / texture->h;
   580     maxtv = (float) (srcrect->y + srcrect->h) / texture->h;
   581 
   582     vertices[0].x = minx;
   583     vertices[0].y = miny;
   584     vertices[0].z = 0.0f;
   585     vertices[0].tu = mintu;
   586     vertices[0].tv = mintv;
   587     vertices[1].x = maxx;
   588     vertices[1].y = miny;
   589     vertices[1].z = 0.0f;
   590     vertices[1].tu = maxtu;
   591     vertices[1].tv = mintv;
   592     vertices[2].x = maxx;
   593     vertices[2].y = maxy;
   594     vertices[2].z = 0.0f;
   595     vertices[2].tu = maxtu;
   596     vertices[2].tv = maxtv;
   597     vertices[3].x = minx;
   598     vertices[3].y = maxy;
   599     vertices[3].z = 0.0f;
   600     vertices[3].tu = mintu;
   601     vertices[3].tv = maxtv;
   602 
   603     result =
   604         IDirect3DDevice9_SetTexture(data->device, 0,
   605                                     (IDirect3DBaseTexture9 *) texturedata->
   606                                     texture);
   607     if (FAILED(result)) {
   608         D3D_SetError("SetTexture()", result);
   609         return -1;
   610     }
   611     result =
   612         IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
   613                                          vertices, sizeof(*vertices));
   614     if (FAILED(result)) {
   615         D3D_SetError("DrawPrimitiveUP()", result);
   616         return -1;
   617     }
   618     return 0;
   619 }
   620 
   621 static int
   622 SDL_D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   623                          void *pixels, int pitch)
   624 {
   625     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   626 
   627     return 0;
   628 }
   629 
   630 static int
   631 SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   632                           const void *pixels, int pitch)
   633 {
   634     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   635 
   636     return 0;
   637 }
   638 
   639 static void
   640 SDL_D3D_RenderPresent(SDL_Renderer * renderer)
   641 {
   642     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   643     HRESULT result;
   644 
   645     if (!data->beginScene) {
   646         IDirect3DDevice9_EndScene(data->device);
   647         data->beginScene = SDL_TRUE;
   648     }
   649 
   650     result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
   651     if (FAILED(result)) {
   652         D3D_SetError("Present()", result);
   653     }
   654 }
   655 
   656 static void
   657 SDL_D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   658 {
   659     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   660 
   661     if (!data) {
   662         return;
   663     }
   664     if (data->texture) {
   665         IDirect3DTexture9_Release(data->texture);
   666     }
   667     SDL_free(data);
   668     texture->driverdata = NULL;
   669 }
   670 
   671 void
   672 SDL_D3D_DestroyRenderer(SDL_Renderer * renderer)
   673 {
   674     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   675 
   676     if (data) {
   677         if (data->device) {
   678             IDirect3DDevice9_Release(data->device);
   679         }
   680         SDL_free(data);
   681     }
   682     SDL_free(renderer);
   683 }
   684 
   685 #endif /* SDL_VIDEO_RENDER_D3D */
   686 
   687 /* vi: set ts=4 sw=4 expandtab: */