src/video/win32/SDL_d3drender.c
changeset 1903 f132024010be
parent 1901 f1828a500391
child 1904 1a713f9d1f71
     1.1 --- a/src/video/win32/SDL_d3drender.c	Thu Jul 13 08:15:35 2006 +0000
     1.2 +++ b/src/video/win32/SDL_d3drender.c	Fri Jul 14 06:40:53 2006 +0000
     1.3 @@ -24,7 +24,6 @@
     1.4  #if SDL_VIDEO_RENDER_D3D
     1.5  
     1.6  #include "SDL_win32video.h"
     1.7 -#include "../SDL_yuv_sw_c.h"
     1.8  
     1.9  /* Direct3D renderer implementation */
    1.10  
    1.11 @@ -32,9 +31,6 @@
    1.12                                              Uint32 flags);
    1.13  static int SDL_D3D_CreateTexture(SDL_Renderer * renderer,
    1.14                                   SDL_Texture * texture);
    1.15 -static int SDL_D3D_QueryTexturePixels(SDL_Renderer * renderer,
    1.16 -                                      SDL_Texture * texture, void **pixels,
    1.17 -                                      int *pitch);
    1.18  static int SDL_D3D_SetTexturePalette(SDL_Renderer * renderer,
    1.19                                       SDL_Texture * texture,
    1.20                                       const SDL_Color * colors, int firstcolor,
    1.21 @@ -85,19 +81,20 @@
    1.22       (SDL_TextureBlendMode_None |
    1.23        SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
    1.24       (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
    1.25 -     11,
    1.26 +     12,
    1.27       {
    1.28        SDL_PixelFormat_Index8,
    1.29 +      SDL_PixelFormat_RGB332,
    1.30 +      SDL_PixelFormat_RGB444,
    1.31        SDL_PixelFormat_RGB555,
    1.32 +      SDL_PixelFormat_ARGB4444,
    1.33 +      SDL_PixelFormat_ARGB1555,
    1.34        SDL_PixelFormat_RGB565,
    1.35        SDL_PixelFormat_RGB888,
    1.36 -      SDL_PixelFormat_BGR888,
    1.37        SDL_PixelFormat_ARGB8888,
    1.38 -      SDL_PixelFormat_RGBA8888,
    1.39 -      SDL_PixelFormat_ABGR8888,
    1.40 -      SDL_PixelFormat_BGRA8888,
    1.41 -      SDL_PixelFormat_YUY2,
    1.42 -      SDL_PixelFormat_UYVY},
    1.43 +      SDL_PixelFormat_ARGB2101010,
    1.44 +      SDL_PixelFormat_UYVY,
    1.45 +      SDL_PixelFormat_YUY2},
    1.46       0,
    1.47       0}
    1.48  };
    1.49 @@ -110,9 +107,15 @@
    1.50  
    1.51  typedef struct
    1.52  {
    1.53 -    SDL_SW_YUVTexture *yuv;
    1.54 +    IDirect3DTexture9 *texture;
    1.55  } SDL_D3D_TextureData;
    1.56  
    1.57 +typedef struct
    1.58 +{
    1.59 +    float x, y, z;
    1.60 +    float tu, tv;
    1.61 +} Vertex;
    1.62 +
    1.63  static void
    1.64  D3D_SetError(const char *prefix, HRESULT result)
    1.65  {
    1.66 @@ -192,18 +195,37 @@
    1.67      SDL_SetError("%s: %s", prefix, error);
    1.68  }
    1.69  
    1.70 -static void
    1.71 -UpdateYUVTextureData(SDL_Texture * texture)
    1.72 +static D3DFORMAT
    1.73 +PixelFormatToD3DFMT(Uint32 format)
    1.74  {
    1.75 -    SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
    1.76 -    SDL_Rect rect;
    1.77 -
    1.78 -    rect.x = 0;
    1.79 -    rect.y = 0;
    1.80 -    rect.w = texture->w;
    1.81 -    rect.h = texture->h;
    1.82 -    //SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
    1.83 -    //                    texture->h, data->pixels, data->pitch);
    1.84 +    switch (format) {
    1.85 +    case SDL_PixelFormat_Index8:
    1.86 +        return D3DFMT_P8;
    1.87 +    case SDL_PixelFormat_RGB332:
    1.88 +        return D3DFMT_R3G3B2;
    1.89 +    case SDL_PixelFormat_RGB444:
    1.90 +        return D3DFMT_X4R4G4B4;
    1.91 +    case SDL_PixelFormat_RGB555:
    1.92 +        return D3DFMT_X1R5G5B5;
    1.93 +    case SDL_PixelFormat_ARGB4444:
    1.94 +        return D3DFMT_A4R4G4B4;
    1.95 +    case SDL_PixelFormat_ARGB1555:
    1.96 +        return D3DFMT_A1R5G5B5;
    1.97 +    case SDL_PixelFormat_RGB565:
    1.98 +        return D3DFMT_R5G6B5;
    1.99 +    case SDL_PixelFormat_RGB888:
   1.100 +        return D3DFMT_X8R8G8B8;
   1.101 +    case SDL_PixelFormat_ARGB8888:
   1.102 +        return D3DFMT_A8R8G8B8;
   1.103 +    case SDL_PixelFormat_ARGB2101010:
   1.104 +        return D3DFMT_A2R10G10B10;
   1.105 +    case SDL_PixelFormat_UYVY:
   1.106 +        return D3DFMT_UYVY;
   1.107 +    case SDL_PixelFormat_YUY2:
   1.108 +        return D3DFMT_YUY2;
   1.109 +    default:
   1.110 +        return D3DFMT_UNKNOWN;
   1.111 +    }
   1.112  }
   1.113  
   1.114  void
   1.115 @@ -243,7 +265,6 @@
   1.116      SDL_zerop(data);
   1.117  
   1.118      renderer->CreateTexture = SDL_D3D_CreateTexture;
   1.119 -    renderer->QueryTexturePixels = SDL_D3D_QueryTexturePixels;
   1.120      renderer->SetTexturePalette = SDL_D3D_SetTexturePalette;
   1.121      renderer->GetTexturePalette = SDL_D3D_GetTexturePalette;
   1.122      renderer->UpdateTexture = SDL_D3D_UpdateTexture;
   1.123 @@ -267,7 +288,12 @@
   1.124      SDL_zero(pparams);
   1.125      pparams.BackBufferWidth = window->w;
   1.126      pparams.BackBufferHeight = window->h;
   1.127 -    pparams.BackBufferFormat = D3DFMT_UNKNOWN;  /* FIXME */
   1.128 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   1.129 +        pparams.BackBufferFormat =
   1.130 +            PixelFormatToD3DFMT(display->fullscreen_mode->format);
   1.131 +    } else {
   1.132 +        pparams.BackBufferFormat = D3DFMT_UNKNOWN;
   1.133 +    }
   1.134      if (flags & SDL_Renderer_PresentFlip2) {
   1.135          pparams.BackBufferCount = 2;
   1.136          pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
   1.137 @@ -283,10 +309,12 @@
   1.138      }
   1.139      if (window->flags & SDL_WINDOW_FULLSCREEN) {
   1.140          pparams.Windowed = FALSE;
   1.141 +        pparams.FullScreen_RefreshRateInHz =
   1.142 +            display->fullscreen_mode->refresh_rate;
   1.143      } else {
   1.144          pparams.Windowed = TRUE;
   1.145 +        pparams.FullScreen_RefreshRateInHz = 0;
   1.146      }
   1.147 -    pparams.FullScreen_RefreshRateInHz = 0;     /* FIXME */
   1.148      pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
   1.149  
   1.150      result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT,        /* FIXME */
   1.151 @@ -301,6 +329,11 @@
   1.152      }
   1.153      data->beginScene = SDL_TRUE;
   1.154  
   1.155 +    /* Set up parameters for rendering */
   1.156 +    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
   1.157 +                                    D3DCULL_NONE);
   1.158 +    IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZ | D3DFVF_TEX1);
   1.159 +
   1.160      return renderer;
   1.161  }
   1.162  
   1.163 @@ -312,6 +345,8 @@
   1.164      SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   1.165      SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   1.166      SDL_D3D_TextureData *data;
   1.167 +    D3DPOOL pool;
   1.168 +    HRESULT result;
   1.169  
   1.170      data = (SDL_D3D_TextureData *) SDL_malloc(sizeof(*data));
   1.171      if (!data) {
   1.172 @@ -322,20 +357,23 @@
   1.173  
   1.174      texture->driverdata = data;
   1.175  
   1.176 -    return 0;
   1.177 -}
   1.178 +    if (texture->access == SDL_TextureAccess_Local) {
   1.179 +        pool = D3DPOOL_MANAGED;
   1.180 +    } else {
   1.181 +        pool = D3DPOOL_DEFAULT;
   1.182 +    }
   1.183 +    result =
   1.184 +        IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
   1.185 +                                       texture->h, 1, 0,
   1.186 +                                       PixelFormatToD3DFMT(texture->format),
   1.187 +                                       pool, &data->texture, NULL);
   1.188 +    if (FAILED(result)) {
   1.189 +        SDL_free(data);
   1.190 +        D3D_SetError("CreateTexture()", result);
   1.191 +        return -1;
   1.192 +    }
   1.193  
   1.194 -static int
   1.195 -SDL_D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
   1.196 -                           void **pixels, int *pitch)
   1.197 -{
   1.198 -    SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.199 -
   1.200 -    if (data->yuv) {
   1.201 -        return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
   1.202 -    } else {
   1.203 -        return 0;
   1.204 -    }
   1.205 +    return 0;
   1.206  }
   1.207  
   1.208  static int
   1.209 @@ -347,12 +385,7 @@
   1.210          (SDL_D3D_RenderData *) renderer->driverdata;
   1.211      SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.212  
   1.213 -    if (data->yuv) {
   1.214 -        SDL_SetError("YUV textures don't have a palette");
   1.215 -        return -1;
   1.216 -    } else {
   1.217 -        return 0;
   1.218 -    }
   1.219 +    return 0;
   1.220  }
   1.221  
   1.222  static int
   1.223 @@ -361,12 +394,7 @@
   1.224  {
   1.225      SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.226  
   1.227 -    if (data->yuv) {
   1.228 -        SDL_SetError("YUV textures don't have a palette");
   1.229 -        return -1;
   1.230 -    } else {
   1.231 -        return 0;
   1.232 -    }
   1.233 +    return 0;
   1.234  }
   1.235  
   1.236  static int
   1.237 @@ -374,19 +402,59 @@
   1.238                        const SDL_Rect * rect, const void *pixels, int pitch)
   1.239  {
   1.240      SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.241 +    SDL_D3D_RenderData *renderdata =
   1.242 +        (SDL_D3D_RenderData *) renderer->driverdata;
   1.243 +    IDirect3DTexture9 *temp;
   1.244 +    RECT d3drect;
   1.245 +    D3DLOCKED_RECT locked;
   1.246 +    const Uint8 *src;
   1.247 +    Uint8 *dst;
   1.248 +    int row, length;
   1.249 +    HRESULT result;
   1.250  
   1.251 -    if (data->yuv) {
   1.252 -        if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
   1.253 -            return -1;
   1.254 -        }
   1.255 -        UpdateYUVTextureData(texture);
   1.256 -        return 0;
   1.257 -    } else {
   1.258 -        SDL_D3D_RenderData *renderdata =
   1.259 -            (SDL_D3D_RenderData *) renderer->driverdata;
   1.260 +    result =
   1.261 +        IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
   1.262 +                                       texture->h, 1, 0,
   1.263 +                                       PixelFormatToD3DFMT(texture->format),
   1.264 +                                       D3DPOOL_SYSTEMMEM, &temp, NULL);
   1.265 +    if (FAILED(result)) {
   1.266 +        D3D_SetError("CreateTexture()", result);
   1.267 +        return -1;
   1.268 +    }
   1.269 +
   1.270 +    d3drect.left = rect->x;
   1.271 +    d3drect.right = rect->x + rect->w;
   1.272 +    d3drect.top = rect->y;
   1.273 +    d3drect.bottom = rect->y + rect->h;
   1.274 +
   1.275 +    result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
   1.276 +    if (FAILED(result)) {
   1.277 +        IDirect3DTexture9_Release(temp);
   1.278 +        D3D_SetError("LockRect()", result);
   1.279 +        return -1;
   1.280 +    }
   1.281  
   1.282 -        return 0;
   1.283 +    src = pixels;
   1.284 +    dst = locked.pBits;
   1.285 +    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
   1.286 +    for (row = 0; row < rect->h; ++row) {
   1.287 +        SDL_memcpy(dst, src, length);
   1.288 +        src += pitch;
   1.289 +        dst += locked.Pitch;
   1.290      }
   1.291 +    IDirect3DTexture9_UnlockRect(temp, 0);
   1.292 +
   1.293 +    result =
   1.294 +        IDirect3DDevice9_UpdateTexture(renderdata->device,
   1.295 +                                       (IDirect3DBaseTexture9 *) temp,
   1.296 +                                       (IDirect3DBaseTexture9 *) data->
   1.297 +                                       texture);
   1.298 +    IDirect3DTexture9_Release(temp);
   1.299 +    if (FAILED(result)) {
   1.300 +        D3D_SetError("UpdateTexture()", result);
   1.301 +        return -1;
   1.302 +    }
   1.303 +    return 0;
   1.304  }
   1.305  
   1.306  static int
   1.307 @@ -395,13 +463,30 @@
   1.308                      int *pitch)
   1.309  {
   1.310      SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.311 +    RECT d3drect;
   1.312 +    D3DLOCKED_RECT locked;
   1.313 +    HRESULT result;
   1.314  
   1.315 -    if (data->yuv) {
   1.316 -        return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
   1.317 -                                     pitch);
   1.318 -    } else {
   1.319 +    if (texture->access != SDL_TextureAccess_Local) {
   1.320 +        SDL_SetError("Can't lock remote video memory");
   1.321          return -1;
   1.322      }
   1.323 +
   1.324 +    d3drect.left = rect->x;
   1.325 +    d3drect.right = rect->x + rect->w;
   1.326 +    d3drect.top = rect->y;
   1.327 +    d3drect.bottom = rect->y + rect->h;
   1.328 +
   1.329 +    result =
   1.330 +        IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
   1.331 +                                   markDirty ? 0 : D3DLOCK_NO_DIRTY_UPDATE);
   1.332 +    if (FAILED(result)) {
   1.333 +        D3D_SetError("LockRect()", result);
   1.334 +        return -1;
   1.335 +    }
   1.336 +    *pixels = locked.pBits;
   1.337 +    *pitch = locked.Pitch;
   1.338 +    return 0;
   1.339  }
   1.340  
   1.341  static void
   1.342 @@ -409,16 +494,27 @@
   1.343  {
   1.344      SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.345  
   1.346 -    if (data->yuv) {
   1.347 -        SDL_SW_UnlockYUVTexture(data->yuv);
   1.348 -        UpdateYUVTextureData(texture);
   1.349 -    }
   1.350 +    IDirect3DTexture9_UnlockRect(data->texture, 0);
   1.351  }
   1.352  
   1.353  static void
   1.354  SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   1.355                       int numrects, const SDL_Rect * rects)
   1.356  {
   1.357 +    SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
   1.358 +    RECT d3drect;
   1.359 +    int i;
   1.360 +
   1.361 +    for (i = 0; i < numrects; ++i) {
   1.362 +        const SDL_Rect *rect = &rects[i];
   1.363 +
   1.364 +        d3drect.left = rect->x;
   1.365 +        d3drect.right = rect->x + rect->w;
   1.366 +        d3drect.top = rect->y;
   1.367 +        d3drect.bottom = rect->y + rect->h;
   1.368 +
   1.369 +        IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
   1.370 +    }
   1.371  }
   1.372  
   1.373  static void
   1.374 @@ -441,11 +537,13 @@
   1.375      }
   1.376  
   1.377      d3drect.x1 = rect->x;
   1.378 -    d3drect.x2 = rect->x+rect->w;
   1.379 +    d3drect.x2 = rect->x + rect->w;
   1.380      d3drect.y1 = rect->y;
   1.381 -    d3drect.y2 = rect->y+rect->h;
   1.382 +    d3drect.y2 = rect->y + rect->h;
   1.383  
   1.384 -    result = IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET, (D3DCOLOR) color, 1.0f, 0);
   1.385 +    result =
   1.386 +        IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET,
   1.387 +                               (D3DCOLOR) color, 1.0f, 0);
   1.388      if (FAILED(result)) {
   1.389          D3D_SetError("Clear()", result);
   1.390          return -1;
   1.391 @@ -461,11 +559,62 @@
   1.392      SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
   1.393      SDL_D3D_TextureData *texturedata =
   1.394          (SDL_D3D_TextureData *) texture->driverdata;
   1.395 +    float minx, miny, maxx, maxy;
   1.396 +    float mintu, maxtu, mintv, maxtv;
   1.397 +    Vertex vertices[4];
   1.398 +    HRESULT result;
   1.399  
   1.400      if (data->beginScene) {
   1.401          IDirect3DDevice9_BeginScene(data->device);
   1.402          data->beginScene = SDL_FALSE;
   1.403      }
   1.404 +
   1.405 +    minx = (float) dstrect->x;
   1.406 +    miny = (float) dstrect->y;
   1.407 +    maxx = (float) dstrect->x + dstrect->w;
   1.408 +    maxy = (float) dstrect->y + dstrect->h;
   1.409 +
   1.410 +    mintu = (float) srcrect->x / texture->w;
   1.411 +    maxtu = (float) (srcrect->x + srcrect->w) / texture->w;
   1.412 +    mintv = (float) srcrect->y / texture->h;
   1.413 +    maxtv = (float) (srcrect->y + srcrect->h) / texture->h;
   1.414 +
   1.415 +    vertices[0].x = minx;
   1.416 +    vertices[0].y = miny;
   1.417 +    vertices[0].z = 0.0f;
   1.418 +    vertices[0].tu = mintu;
   1.419 +    vertices[0].tv = mintv;
   1.420 +    vertices[1].x = maxx;
   1.421 +    vertices[1].y = miny;
   1.422 +    vertices[1].z = 0.0f;
   1.423 +    vertices[1].tu = maxtu;
   1.424 +    vertices[1].tv = mintv;
   1.425 +    vertices[2].x = maxx;
   1.426 +    vertices[2].y = maxy;
   1.427 +    vertices[2].z = 0.0f;
   1.428 +    vertices[2].tu = maxtu;
   1.429 +    vertices[2].tv = maxtv;
   1.430 +    vertices[3].x = minx;
   1.431 +    vertices[3].y = maxy;
   1.432 +    vertices[3].z = 0.0f;
   1.433 +    vertices[3].tu = mintu;
   1.434 +    vertices[3].tv = maxtv;
   1.435 +
   1.436 +    result =
   1.437 +        IDirect3DDevice9_SetTexture(data->device, 0,
   1.438 +                                    (IDirect3DBaseTexture9 *) texturedata->
   1.439 +                                    texture);
   1.440 +    if (FAILED(result)) {
   1.441 +        D3D_SetError("SetTexture()", result);
   1.442 +        return -1;
   1.443 +    }
   1.444 +    result =
   1.445 +        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
   1.446 +                                         vertices, sizeof(*vertices));
   1.447 +    if (FAILED(result)) {
   1.448 +        D3D_SetError("DrawPrimitiveUP()", result);
   1.449 +        return -1;
   1.450 +    }
   1.451      return 0;
   1.452  }
   1.453  
   1.454 @@ -512,6 +661,9 @@
   1.455      if (!data) {
   1.456          return;
   1.457      }
   1.458 +    if (data->texture) {
   1.459 +        IDirect3DTexture9_Release(data->texture);
   1.460 +    }
   1.461      SDL_free(data);
   1.462      texture->driverdata = NULL;
   1.463  }