render: first (untested!) shot at converting D3D11 renderer to new interfaces. SDL-ryan-batching-renderer
authorRyan C. Gordon <icculus@icculus.org>
Wed, 03 Oct 2018 00:52:37 -0400
branchSDL-ryan-batching-renderer
changeset 122836c108f3716d5
parent 12282 2395434a074d
child 12286 75abb8e13a91
render: first (untested!) shot at converting D3D11 renderer to new interfaces.

Probably doesn't even compile yet.
src/render/direct3d11/SDL_render_d3d11.c
     1.1 --- a/src/render/direct3d11/SDL_render_d3d11.c	Mon Oct 01 22:53:45 2018 -0400
     1.2 +++ b/src/render/direct3d11/SDL_render_d3d11.c	Wed Oct 03 00:52:37 2018 -0400
     1.3 @@ -56,6 +56,9 @@
     1.4  #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; }
     1.5  
     1.6  
     1.7 +/* !!! FIXME: vertex buffer bandwidth could be significantly lower; move color to a uniform, only use UV coords
     1.8 +   !!! FIXME:  when textures are needed, and don't ever pass Z, since it's always zero. */
     1.9 +
    1.10  /* Vertex shader, common values */
    1.11  typedef struct
    1.12  {
    1.13 @@ -145,6 +148,12 @@
    1.14      ID3D11PixelShader *currentShader;
    1.15      ID3D11ShaderResourceView *currentShaderResource;
    1.16      ID3D11SamplerState *currentSampler;
    1.17 +    SDL_bool cliprectDirty;
    1.18 +    SDL_bool currentCliprectEnabled;
    1.19 +    SDL_Rect currentCliprect;
    1.20 +    SDL_Rect currentViewport;
    1.21 +    int currentViewportRotation;
    1.22 +    SDL_bool viewportDirty;
    1.23  } D3D11_RenderData;
    1.24  
    1.25  
    1.26 @@ -175,75 +184,6 @@
    1.27  #endif
    1.28  
    1.29  
    1.30 -/* Direct3D 11.1 renderer implementation */
    1.31 -static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
    1.32 -static void D3D11_WindowEvent(SDL_Renderer * renderer,
    1.33 -                            const SDL_WindowEvent *event);
    1.34 -static SDL_bool D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
    1.35 -static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    1.36 -static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    1.37 -                             const SDL_Rect * rect, const void *srcPixels,
    1.38 -                             int srcPitch);
    1.39 -static int D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
    1.40 -                                  const SDL_Rect * rect,
    1.41 -                                  const Uint8 *Yplane, int Ypitch,
    1.42 -                                  const Uint8 *Uplane, int Upitch,
    1.43 -                                  const Uint8 *Vplane, int Vpitch);
    1.44 -static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    1.45 -                             const SDL_Rect * rect, void **pixels, int *pitch);
    1.46 -static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    1.47 -static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
    1.48 -static int D3D11_UpdateViewport(SDL_Renderer * renderer);
    1.49 -static int D3D11_UpdateClipRect(SDL_Renderer * renderer);
    1.50 -static int D3D11_RenderClear(SDL_Renderer * renderer);
    1.51 -static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
    1.52 -                                  const SDL_FPoint * points, int count);
    1.53 -static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
    1.54 -                                 const SDL_FPoint * points, int count);
    1.55 -static int D3D11_RenderFillRects(SDL_Renderer * renderer,
    1.56 -                                 const SDL_FRect * rects, int count);
    1.57 -static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    1.58 -                            const SDL_Rect * srcrect, const SDL_FRect * dstrect);
    1.59 -static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
    1.60 -                              const SDL_Rect * srcrect, const SDL_FRect * dstrect,
    1.61 -                              const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
    1.62 -static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.63 -                                  Uint32 format, void * pixels, int pitch);
    1.64 -static void D3D11_RenderPresent(SDL_Renderer * renderer);
    1.65 -static void D3D11_DestroyTexture(SDL_Renderer * renderer,
    1.66 -                                 SDL_Texture * texture);
    1.67 -static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
    1.68 -
    1.69 -/* Direct3D 11.1 Internal Functions */
    1.70 -static HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
    1.71 -static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
    1.72 -static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
    1.73 -static HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
    1.74 -static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer);
    1.75 -
    1.76 -SDL_RenderDriver D3D11_RenderDriver = {
    1.77 -    D3D11_CreateRenderer,
    1.78 -    {
    1.79 -        "direct3d11",
    1.80 -        (
    1.81 -            SDL_RENDERER_ACCELERATED |
    1.82 -            SDL_RENDERER_PRESENTVSYNC |
    1.83 -            SDL_RENDERER_TARGETTEXTURE
    1.84 -        ),                          /* flags.  see SDL_RendererFlags */
    1.85 -        6,                          /* num_texture_formats */
    1.86 -        {                           /* texture_formats */
    1.87 -            SDL_PIXELFORMAT_ARGB8888,
    1.88 -            SDL_PIXELFORMAT_RGB888,
    1.89 -            SDL_PIXELFORMAT_YV12,
    1.90 -            SDL_PIXELFORMAT_IYUV,
    1.91 -            SDL_PIXELFORMAT_NV12,
    1.92 -            SDL_PIXELFORMAT_NV21
    1.93 -        },
    1.94 -        0,                          /* max_texture_width: will be filled in later */
    1.95 -        0                           /* max_texture_height: will be filled in later */
    1.96 -    }
    1.97 -};
    1.98 -
    1.99  
   1.100  Uint32
   1.101  D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat)
   1.102 @@ -276,85 +216,6 @@
   1.103      }
   1.104  }
   1.105  
   1.106 -SDL_Renderer *
   1.107 -D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
   1.108 -{
   1.109 -    SDL_Renderer *renderer;
   1.110 -    D3D11_RenderData *data;
   1.111 -
   1.112 -    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
   1.113 -    if (!renderer) {
   1.114 -        SDL_OutOfMemory();
   1.115 -        return NULL;
   1.116 -    }
   1.117 -
   1.118 -    data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
   1.119 -    if (!data) {
   1.120 -        SDL_OutOfMemory();
   1.121 -        return NULL;
   1.122 -    }
   1.123 -
   1.124 -    renderer->WindowEvent = D3D11_WindowEvent;
   1.125 -    renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
   1.126 -    renderer->CreateTexture = D3D11_CreateTexture;
   1.127 -    renderer->UpdateTexture = D3D11_UpdateTexture;
   1.128 -    renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
   1.129 -    renderer->LockTexture = D3D11_LockTexture;
   1.130 -    renderer->UnlockTexture = D3D11_UnlockTexture;
   1.131 -    renderer->SetRenderTarget = D3D11_SetRenderTarget;
   1.132 -    renderer->UpdateViewport = D3D11_UpdateViewport;
   1.133 -    renderer->UpdateClipRect = D3D11_UpdateClipRect;
   1.134 -    renderer->RenderClear = D3D11_RenderClear;
   1.135 -    renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
   1.136 -    renderer->RenderDrawLines = D3D11_RenderDrawLines;
   1.137 -    renderer->RenderFillRects = D3D11_RenderFillRects;
   1.138 -    renderer->RenderCopy = D3D11_RenderCopy;
   1.139 -    renderer->RenderCopyEx = D3D11_RenderCopyEx;
   1.140 -    renderer->RenderReadPixels = D3D11_RenderReadPixels;
   1.141 -    renderer->RenderPresent = D3D11_RenderPresent;
   1.142 -    renderer->DestroyTexture = D3D11_DestroyTexture;
   1.143 -    renderer->DestroyRenderer = D3D11_DestroyRenderer;
   1.144 -    renderer->info = D3D11_RenderDriver.info;
   1.145 -    renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
   1.146 -    renderer->driverdata = data;
   1.147 -
   1.148 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   1.149 -    /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
   1.150 -     * Failure to use it seems to either result in:
   1.151 -     *
   1.152 -     *  - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
   1.153 -     *    off (framerate doesn't get capped), but nothing appears on-screen
   1.154 -     *
   1.155 -     *  - with the D3D11 debug runtime turned ON, vsync gets automatically
   1.156 -     *    turned back on, and the following gets output to the debug console:
   1.157 -     *    
   1.158 -     *    DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ] 
   1.159 -     */
   1.160 -    renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
   1.161 -#else
   1.162 -    if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
   1.163 -        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
   1.164 -    }
   1.165 -#endif
   1.166 -
   1.167 -    /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
   1.168 -     * order to give init functions access to the underlying window handle:
   1.169 -     */
   1.170 -    renderer->window = window;
   1.171 -
   1.172 -    /* Initialize Direct3D resources */
   1.173 -    if (FAILED(D3D11_CreateDeviceResources(renderer))) {
   1.174 -        D3D11_DestroyRenderer(renderer);
   1.175 -        return NULL;
   1.176 -    }
   1.177 -    if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
   1.178 -        D3D11_DestroyRenderer(renderer);
   1.179 -        return NULL;
   1.180 -    }
   1.181 -
   1.182 -    return renderer;
   1.183 -}
   1.184 -
   1.185  static void
   1.186  D3D11_ReleaseAll(SDL_Renderer * renderer)
   1.187  {
   1.188 @@ -1066,11 +927,7 @@
   1.189          goto done;
   1.190      }
   1.191  
   1.192 -    if (D3D11_UpdateViewport(renderer) != 0) {
   1.193 -        /* D3D11_UpdateViewport will set the SDL error if it fails. */
   1.194 -        result = E_FAIL;
   1.195 -        goto done;
   1.196 -    }
   1.197 +    data->viewportDirty = SDL_TRUE;
   1.198  
   1.199  done:
   1.200      SAFE_RELEASE(backBuffer);
   1.201 @@ -1671,184 +1528,265 @@
   1.202      return 0;
   1.203  }
   1.204  
   1.205 -static void
   1.206 -D3D11_SetModelMatrix(SDL_Renderer *renderer, const Float4X4 *matrix)
   1.207 +static int
   1.208 +D3D11_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
   1.209  {
   1.210 -    D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
   1.211 -
   1.212 -    if (matrix) {
   1.213 -        data->vertexShaderConstantsData.model = *matrix;
   1.214 -    } else {
   1.215 -        data->vertexShaderConstantsData.model = MatrixIdentity();
   1.216 -    }
   1.217 -
   1.218 -    ID3D11DeviceContext_UpdateSubresource(data->d3dContext,
   1.219 -        (ID3D11Resource *)data->vertexShaderConstants,
   1.220 -        0,
   1.221 -        NULL,
   1.222 -        &data->vertexShaderConstantsData,
   1.223 -        0,
   1.224 -        0
   1.225 -        );
   1.226 +    return 0;  /* nothing to do in this backend. */
   1.227  }
   1.228  
   1.229  static int
   1.230 -D3D11_UpdateViewport(SDL_Renderer * renderer)
   1.231 +D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
   1.232  {
   1.233 -    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   1.234 -    Float4X4 projection;
   1.235 -    Float4X4 view;
   1.236 -    SDL_FRect orientationAlignedViewport;
   1.237 -    BOOL swapDimensions;
   1.238 -    D3D11_VIEWPORT viewport;
   1.239 -    const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
   1.240 +    VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
   1.241 +    const float r = (float)(cmd->data.draw.r / 255.0f);
   1.242 +    const float g = (float)(cmd->data.draw.g / 255.0f);
   1.243 +    const float b = (float)(cmd->data.draw.b / 255.0f);
   1.244 +    const float a = (float)(cmd->data.draw.a / 255.0f);
   1.245 +    size_t i;
   1.246  
   1.247 -    if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
   1.248 -        /* If the viewport is empty, assume that it is because
   1.249 -         * SDL_CreateRenderer is calling it, and will call it again later
   1.250 -         * with a non-empty viewport.
   1.251 -         */
   1.252 -        /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
   1.253 -        return 0;
   1.254 +    if (!verts) {
   1.255 +        return -1;
   1.256      }
   1.257  
   1.258 -    /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
   1.259 -     * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
   1.260 -     * default coordinate system) so rotations will be done in the opposite
   1.261 -     * direction of the DXGI_MODE_ROTATION enumeration.
   1.262 -     */
   1.263 -    switch (rotation) {
   1.264 -        case DXGI_MODE_ROTATION_IDENTITY:
   1.265 -            projection = MatrixIdentity();
   1.266 -            break;
   1.267 -        case DXGI_MODE_ROTATION_ROTATE270:
   1.268 -            projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
   1.269 -            break;
   1.270 -        case DXGI_MODE_ROTATION_ROTATE180:
   1.271 -            projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
   1.272 -            break;
   1.273 -        case DXGI_MODE_ROTATION_ROTATE90:
   1.274 -            projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
   1.275 -            break;
   1.276 -        default:
   1.277 -            return SDL_SetError("An unknown DisplayOrientation is being used");
   1.278 +    for (i = 0; i < count; i++) {
   1.279 +        verts->pos.x = points[i].x + 0.5f;
   1.280 +        verts->pos.y = points[i].y + 0.5f;
   1.281 +        verts->pos.z = 0.0f
   1.282 +        verts->tex.u = 0.0f
   1.283 +        verts->tex.v = 0.0f
   1.284 +        verts->color.r = r;
   1.285 +        verts->color.g = g;
   1.286 +        verts->color.b = b;
   1.287 +        verts->color.a = a;
   1.288 +        verts++;
   1.289      }
   1.290  
   1.291 -    /* Update the view matrix */
   1.292 -    view.m[0][0] = 2.0f / renderer->viewport.w;
   1.293 -    view.m[0][1] = 0.0f;
   1.294 -    view.m[0][2] = 0.0f;
   1.295 -    view.m[0][3] = 0.0f;
   1.296 -    view.m[1][0] = 0.0f;
   1.297 -    view.m[1][1] = -2.0f / renderer->viewport.h;
   1.298 -    view.m[1][2] = 0.0f;
   1.299 -    view.m[1][3] = 0.0f;
   1.300 -    view.m[2][0] = 0.0f;
   1.301 -    view.m[2][1] = 0.0f;
   1.302 -    view.m[2][2] = 1.0f;
   1.303 -    view.m[2][3] = 0.0f;
   1.304 -    view.m[3][0] = -1.0f;
   1.305 -    view.m[3][1] = 1.0f;
   1.306 -    view.m[3][2] = 0.0f;
   1.307 -    view.m[3][3] = 1.0f;
   1.308 -
   1.309 -    /* Combine the projection + view matrix together now, as both only get
   1.310 -     * set here (as of this writing, on Dec 26, 2013).  When done, store it
   1.311 -     * for eventual transfer to the GPU.
   1.312 -     */
   1.313 -    data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
   1.314 -            view,
   1.315 -            projection);
   1.316 -
   1.317 -    /* Reset the model matrix */
   1.318 -    D3D11_SetModelMatrix(renderer, NULL);
   1.319 -
   1.320 -    /* Update the Direct3D viewport, which seems to be aligned to the
   1.321 -     * swap buffer's coordinate space, which is always in either
   1.322 -     * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
   1.323 -     * for Windows Phone devices.
   1.324 -     */
   1.325 -    swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation);
   1.326 -    if (swapDimensions) {
   1.327 -        orientationAlignedViewport.x = (float) renderer->viewport.y;
   1.328 -        orientationAlignedViewport.y = (float) renderer->viewport.x;
   1.329 -        orientationAlignedViewport.w = (float) renderer->viewport.h;
   1.330 -        orientationAlignedViewport.h = (float) renderer->viewport.w;
   1.331 -    } else {
   1.332 -        orientationAlignedViewport.x = (float) renderer->viewport.x;
   1.333 -        orientationAlignedViewport.y = (float) renderer->viewport.y;
   1.334 -        orientationAlignedViewport.w = (float) renderer->viewport.w;
   1.335 -        orientationAlignedViewport.h = (float) renderer->viewport.h;
   1.336 -    }
   1.337 -    /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
   1.338 -
   1.339 -    viewport.TopLeftX = orientationAlignedViewport.x;
   1.340 -    viewport.TopLeftY = orientationAlignedViewport.y;
   1.341 -    viewport.Width = orientationAlignedViewport.w;
   1.342 -    viewport.Height = orientationAlignedViewport.h;
   1.343 -    viewport.MinDepth = 0.0f;
   1.344 -    viewport.MaxDepth = 1.0f;
   1.345 -    /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, viewport.TopLeftX, viewport.TopLeftY, viewport.Width, viewport.Height); */
   1.346 -    ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
   1.347 -
   1.348      return 0;
   1.349  }
   1.350  
   1.351  static int
   1.352 -D3D11_UpdateClipRect(SDL_Renderer * renderer)
   1.353 +D3D11_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
   1.354  {
   1.355 -    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   1.356 +    VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
   1.357 +    const float r = (float)(cmd->data.draw.r / 255.0f);
   1.358 +    const float g = (float)(cmd->data.draw.g / 255.0f);
   1.359 +    const float b = (float)(cmd->data.draw.b / 255.0f);
   1.360 +    const float a = (float)(cmd->data.draw.a / 255.0f);
   1.361 +    size_t i;
   1.362  
   1.363 -    if (!renderer->clipping_enabled) {
   1.364 -        ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
   1.365 -    } else {
   1.366 -        D3D11_RECT scissorRect;
   1.367 -        if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect, TRUE) != 0) {
   1.368 -            /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
   1.369 -            return -1;
   1.370 -        }
   1.371 -        ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 1, &scissorRect);
   1.372 +    if (!verts) {
   1.373 +        return -1;
   1.374 +    }
   1.375 +
   1.376 +    for (i = 0; i < count; i++) {
   1.377 +        verts->pos.x = rects[i].x;
   1.378 +        verts->pos.y = rects[i].y;
   1.379 +        verts->pos.z = 0.0f
   1.380 +        verts->tex.u = 0.0f
   1.381 +        verts->tex.v = 0.0f
   1.382 +        verts->color.r = r;
   1.383 +        verts->color.g = g;
   1.384 +        verts->color.b = b;
   1.385 +        verts->color.a = a;
   1.386 +        verts++;
   1.387 +
   1.388 +        verts->pos.x = rects[i].x;
   1.389 +        verts->pos.y = rects[i].y + rects[i].h;
   1.390 +        verts->pos.z = 0.0f
   1.391 +        verts->tex.u = 0.0f
   1.392 +        verts->tex.v = 0.0f
   1.393 +        verts->color.r = r;
   1.394 +        verts->color.g = g;
   1.395 +        verts->color.b = b;
   1.396 +        verts->color.a = a;
   1.397 +        verts++;
   1.398 +
   1.399 +        verts->pos.x = rects[i].x + rects[i].w;
   1.400 +        verts->pos.y = rects[i].y;
   1.401 +        verts->pos.z = 0.0f
   1.402 +        verts->tex.u = 0.0f
   1.403 +        verts->tex.v = 0.0f
   1.404 +        verts->color.r = r;
   1.405 +        verts->color.g = g;
   1.406 +        verts->color.b = b;
   1.407 +        verts->color.a = a;
   1.408 +        verts++;
   1.409 +
   1.410 +        verts->pos.x = rects[i].x + rects[i].w;
   1.411 +        verts->pos.y = rects[i].y + rects[i].h;
   1.412 +        verts->pos.z = 0.0f
   1.413 +        verts->tex.u = 0.0f
   1.414 +        verts->tex.v = 0.0f
   1.415 +        verts->color.r = r;
   1.416 +        verts->color.g = g;
   1.417 +        verts->color.b = b;
   1.418 +        verts->color.a = a;
   1.419 +        verts++;
   1.420      }
   1.421  
   1.422      return 0;
   1.423  }
   1.424  
   1.425 -static void
   1.426 -D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
   1.427 +static int
   1.428 +D3D11_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
   1.429 +             const SDL_Rect * srcrect, const SDL_FRect * dstrect)
   1.430  {
   1.431 -    D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
   1.432 -    ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
   1.433 -    SAFE_RELEASE(data->mainRenderTargetView);
   1.434 -}
   1.435 +    VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
   1.436 +    const float r = (float)(cmd->data.draw.r / 255.0f);
   1.437 +    const float g = (float)(cmd->data.draw.g / 255.0f);
   1.438 +    const float b = (float)(cmd->data.draw.b / 255.0f);
   1.439 +    const float a = (float)(cmd->data.draw.a / 255.0f);
   1.440 +    const float minu = (float) srcrect->x / texture->w;
   1.441 +    const float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
   1.442 +    const float minv = (float) srcrect->y / texture->h;
   1.443 +    const float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
   1.444  
   1.445 -static ID3D11RenderTargetView *
   1.446 -D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
   1.447 -{
   1.448 -    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   1.449 -    if (data->currentOffscreenRenderTargetView) {
   1.450 -        return data->currentOffscreenRenderTargetView;
   1.451 -    } else {
   1.452 -        return data->mainRenderTargetView;
   1.453 +    if (!verts) {
   1.454 +        return -1;
   1.455      }
   1.456 +
   1.457 +    verts->pos.x = dstrect->x;
   1.458 +    verts->pos.y = dstrect->y;
   1.459 +    verts->pos.z = 0.0f;
   1.460 +    verts->tex.x = minu;
   1.461 +    verts->tex.y = minv;
   1.462 +    verts->color.r = r;
   1.463 +    verts->color.g = g;
   1.464 +    verts->color.b = b;
   1.465 +    verts->color.a = a;
   1.466 +    verts++;
   1.467 +
   1.468 +    verts->pos.x = dstrect->x;
   1.469 +    verts->pos.y = dstrect->y + dstrect->h;
   1.470 +    verts->pos.z = 0.0f;
   1.471 +    verts->tex.x = minu;
   1.472 +    verts->tex.y = maxv;
   1.473 +    verts->color.r = r;
   1.474 +    verts->color.g = g;
   1.475 +    verts->color.b = b;
   1.476 +    verts->color.a = a;
   1.477 +    verts++;
   1.478 +
   1.479 +    verts->pos.x = dstrect->x + dstrect->w;
   1.480 +    verts->pos.y = dstrect->y;
   1.481 +    verts->pos.z = 0.0f;
   1.482 +    verts->tex.x = maxu;
   1.483 +    verts->tex.y = minv;
   1.484 +    verts->color.r = r;
   1.485 +    verts->color.g = g;
   1.486 +    verts->color.b = b;
   1.487 +    verts->color.a = a;
   1.488 +    verts++;
   1.489 +
   1.490 +    verts->pos.x = dstrect->x + dstrect->w;
   1.491 +    verts->pos.y = dstrect->y + dstrect->h;
   1.492 +    verts->pos.z = 0.0f;
   1.493 +    verts->tex.x = maxu;
   1.494 +    verts->tex.y = maxv;
   1.495 +    verts->color.r = r;
   1.496 +    verts->color.g = g;
   1.497 +    verts->color.b = b;
   1.498 +    verts->color.a = a;
   1.499 +    verts++;
   1.500 +
   1.501 +    return 0;
   1.502  }
   1.503  
   1.504  static int
   1.505 -D3D11_RenderClear(SDL_Renderer * renderer)
   1.506 +D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
   1.507 +               const SDL_Rect * srcrect, const SDL_FRect * dstrect,
   1.508 +               const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
   1.509  {
   1.510 -    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   1.511 -    const float colorRGBA[] = {
   1.512 -        (renderer->r / 255.0f),
   1.513 -        (renderer->g / 255.0f),
   1.514 -        (renderer->b / 255.0f),
   1.515 -        (renderer->a / 255.0f)
   1.516 -    };
   1.517 -    ID3D11DeviceContext_ClearRenderTargetView(data->d3dContext,
   1.518 -        D3D11_GetCurrentRenderTargetView(renderer),
   1.519 -        colorRGBA
   1.520 -        );
   1.521 +    VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 5 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
   1.522 +    const float r = (float)(cmd->data.draw.r / 255.0f);
   1.523 +    const float g = (float)(cmd->data.draw.g / 255.0f);
   1.524 +    const float b = (float)(cmd->data.draw.b / 255.0f);
   1.525 +    const float a = (float)(cmd->data.draw.a / 255.0f);
   1.526 +    float minx, miny, maxx, maxy;
   1.527 +    float minu, maxu, minv, maxv;
   1.528 +
   1.529 +    if (flip & SDL_FLIP_HORIZONTAL) {
   1.530 +        minu = (float) srcrect->x / texture->w;
   1.531 +        maxu = (float) (srcrect->x + srcrect->w) / texture->w;
   1.532 +    } else {
   1.533 +        minu = (float) (srcrect->x + srcrect->w) / texture->w;
   1.534 +        maxu = (float) srcrect->x / texture->w;
   1.535 +    }
   1.536 +
   1.537 +    }
   1.538 +    if (flip & SDL_FLIP_VERTICAL) {
   1.539 +        minv = (float) srcrect->y / texture->h;
   1.540 +        maxv = (float) (srcrect->y + srcrect->h) / texture->h;
   1.541 +    } else {
   1.542 +        minv = (float) (srcrect->y + srcrect->h) / texture->h;
   1.543 +        maxv = (float) srcrect->y / texture->h;
   1.544 +    }
   1.545 +
   1.546 +    minx = -center->x;
   1.547 +    maxx = dstrect->w - center->x;
   1.548 +    miny = -center->y;
   1.549 +    maxy = dstrect->h - center->y;
   1.550 +
   1.551 +    verts->pos.x = minx;
   1.552 +    verts->pos.y = miny;
   1.553 +    verts->pos.z = 0.0f;
   1.554 +    verts->tex.x = minu;
   1.555 +    verts->tex.y = minv;
   1.556 +    verts->color.r = r;
   1.557 +    verts->color.g = g;
   1.558 +    verts->color.b = b;
   1.559 +    verts->color.a = a;
   1.560 +    verts++;
   1.561 +
   1.562 +    verts->pos.x = minx;
   1.563 +    verts->pos.y = maxy;
   1.564 +    verts->pos.z = 0.0f;
   1.565 +    verts->tex.x = minu;
   1.566 +    verts->tex.y = maxv;
   1.567 +    verts->color.r = r;
   1.568 +    verts->color.g = g;
   1.569 +    verts->color.b = b;
   1.570 +    verts->color.a = a;
   1.571 +    verts++;
   1.572 +
   1.573 +    verts->pos.x = maxx;
   1.574 +    verts->pos.y = miny;
   1.575 +    verts->pos.z = 0.0f;
   1.576 +    verts->tex.x = maxu;
   1.577 +    verts->tex.y = minv;
   1.578 +    verts->color.r = r;
   1.579 +    verts->color.g = g;
   1.580 +    verts->color.b = b;
   1.581 +    verts->color.a = a;
   1.582 +    verts++;
   1.583 +
   1.584 +    verts->pos.x = maxx;
   1.585 +    verts->pos.y = maxy;
   1.586 +    verts->pos.z = 0.0f;
   1.587 +    verts->tex.x = maxu;
   1.588 +    verts->tex.y = maxv;
   1.589 +    verts->color.r = r;
   1.590 +    verts->color.g = g;
   1.591 +    verts->color.b = b;
   1.592 +    verts->color.a = a;
   1.593 +    verts++;
   1.594 +
   1.595 +    verts->pos.x = dstrect->x + center->x;  /* X translation */
   1.596 +    verts->pos.y = dstrect->y + center->y;  /* Y translation */
   1.597 +    verts->pos.z = (float)(M_PI * (float) angle / 180.0f);  /* rotation */
   1.598 +    verts->tex.u = 0.0f;
   1.599 +    verts->tex.v = 0.0f;
   1.600 +    verts->color.r = 0;
   1.601 +    verts->color.g = 0;
   1.602 +    verts->color.b = 0;
   1.603 +    verts->color.a = 0;
   1.604 +    verts++;
   1.605 +
   1.606      return 0;
   1.607  }
   1.608  
   1.609 +
   1.610 +/* !!! FIXME: rotate through a few vertex buffers so the GPU has time to finish using them */
   1.611  static int
   1.612  D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
   1.613                           const void * vertexData, size_t dataSizeInBytes)
   1.614 @@ -1916,12 +1854,114 @@
   1.615      return 0;
   1.616  }
   1.617  
   1.618 -static void
   1.619 -D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
   1.620 +static int
   1.621 +D3D11_UpdateViewport(SDL_Renderer * renderer)
   1.622 +{
   1.623 +    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   1.624 +    const SDL_Rect *viewport = &data->currentViewport;
   1.625 +    Float4X4 projection;
   1.626 +    Float4X4 view;
   1.627 +    SDL_FRect orientationAlignedViewport;
   1.628 +    BOOL swapDimensions;
   1.629 +    D3D11_VIEWPORT d3dviewport;
   1.630 +    const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
   1.631 +
   1.632 +    if (viewport->w == 0 || viewport->h == 0) {
   1.633 +        /* If the viewport is empty, assume that it is because
   1.634 +         * SDL_CreateRenderer is calling it, and will call it again later
   1.635 +         * with a non-empty viewport.
   1.636 +         */
   1.637 +        /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
   1.638 +        return 0;
   1.639 +    }
   1.640 +
   1.641 +    /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
   1.642 +     * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
   1.643 +     * default coordinate system) so rotations will be done in the opposite
   1.644 +     * direction of the DXGI_MODE_ROTATION enumeration.
   1.645 +     */
   1.646 +    switch (rotation) {
   1.647 +        case DXGI_MODE_ROTATION_IDENTITY:
   1.648 +            projection = MatrixIdentity();
   1.649 +            break;
   1.650 +        case DXGI_MODE_ROTATION_ROTATE270:
   1.651 +            projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
   1.652 +            break;
   1.653 +        case DXGI_MODE_ROTATION_ROTATE180:
   1.654 +            projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
   1.655 +            break;
   1.656 +        case DXGI_MODE_ROTATION_ROTATE90:
   1.657 +            projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
   1.658 +            break;
   1.659 +        default:
   1.660 +            return SDL_SetError("An unknown DisplayOrientation is being used");
   1.661 +    }
   1.662 +
   1.663 +    /* Update the view matrix */
   1.664 +    SDL_zero(view);
   1.665 +    view.m[0][0] = 2.0f / viewport->w;
   1.666 +    view.m[1][1] = -2.0f / viewport->h;
   1.667 +    view.m[2][2] = 1.0f;
   1.668 +    view.m[3][0] = -1.0f;
   1.669 +    view.m[3][1] = 1.0f;
   1.670 +    view.m[3][3] = 1.0f;
   1.671 +
   1.672 +    /* Combine the projection + view matrix together now, as both only get
   1.673 +     * set here (as of this writing, on Dec 26, 2013).  When done, store it
   1.674 +     * for eventual transfer to the GPU.
   1.675 +     */
   1.676 +    data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
   1.677 +            view,
   1.678 +            projection);
   1.679 +
   1.680 +    /* Update the Direct3D viewport, which seems to be aligned to the
   1.681 +     * swap buffer's coordinate space, which is always in either
   1.682 +     * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
   1.683 +     * for Windows Phone devices.
   1.684 +     */
   1.685 +    swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation);
   1.686 +    if (swapDimensions) {
   1.687 +        orientationAlignedViewport.x = (float) viewport->y;
   1.688 +        orientationAlignedViewport.y = (float) viewport->x;
   1.689 +        orientationAlignedViewport.w = (float) viewport->h;
   1.690 +        orientationAlignedViewport.h = (float) viewport->w;
   1.691 +    } else {
   1.692 +        orientationAlignedViewport.x = (float) viewport->x;
   1.693 +        orientationAlignedViewport.y = (float) viewport->y;
   1.694 +        orientationAlignedViewport.w = (float) viewport->w;
   1.695 +        orientationAlignedViewport.h = (float) viewport->h;
   1.696 +    }
   1.697 +    /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
   1.698 +
   1.699 +    d3dviewport.TopLeftX = orientationAlignedViewport.x;
   1.700 +    d3dviewport.TopLeftY = orientationAlignedViewport.y;
   1.701 +    d3dviewport.Width = orientationAlignedViewport.w;
   1.702 +    d3dviewport.Height = orientationAlignedViewport.h;
   1.703 +    d3dviewport.MinDepth = 0.0f;
   1.704 +    d3dviewport.MaxDepth = 1.0f;
   1.705 +    /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, d3dviewport.TopLeftX, d3dviewport.TopLeftY, d3dviewport.Width, d3dviewport.Height); */
   1.706 +    ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &d3dviewport);
   1.707 +
   1.708 +    data->viewportDirty = SDL_FALSE;
   1.709 +
   1.710 +    return 0;
   1.711 +}
   1.712 +
   1.713 +static int
   1.714 +D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11PixelShader * shader,
   1.715 +                     const int numShaderResources, ID3D11ShaderResourceView ** shaderResources,
   1.716 +                     ID3D11SamplerState * sampler, const Float4X4 *matrix)
   1.717 +
   1.718  {
   1.719      D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
   1.720 +    static const Float4X4 identity = MatrixIdentity();
   1.721 +    const Float4X4 *newmatrix = matrix ? matrix : &identity;
   1.722      ID3D11RasterizerState *rasterizerState;
   1.723      ID3D11RenderTargetView *renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
   1.724 +    ID3D11ShaderResourceView *shaderResource;
   1.725 +    const SDL_BlendMode blendMode = cmd->data.draw.blend;
   1.726 +    ID3D11BlendState *blendState = NULL;
   1.727 +
   1.728      if (renderTargetView != rendererData->currentRenderTargetView) {
   1.729          ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext,
   1.730              1,
   1.731 @@ -1931,7 +1971,25 @@
   1.732          rendererData->currentRenderTargetView = renderTargetView;
   1.733      }
   1.734  
   1.735 -    if (!renderer->clipping_enabled) {
   1.736 +    if (rendererData->viewportDirty) {
   1.737 +        D3D11_UpdateViewport(renderer);
   1.738 +    }
   1.739 +
   1.740 +    if (rendererData->cliprectDirty) {
   1.741 +        if (!rendererData->currentCliprectEnabled) {
   1.742 +            ID3D11DeviceContext_RSSetScissorRects(rendererData->d3dContext, 0, NULL);
   1.743 +        } else {
   1.744 +            D3D11_RECT scissorRect;
   1.745 +            if (D3D11_GetViewportAlignedD3DRect(renderer, &rendererData->currentCliprect, &scissorRect, TRUE) != 0) {
   1.746 +                /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
   1.747 +                return -1;
   1.748 +            }
   1.749 +            ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 1, &scissorRect);
   1.750 +        }
   1.751 +        rendererData->cliprectDirty = SDL_FALSE;
   1.752 +    }
   1.753 +
   1.754 +    if (!rendererData->currentCliprectEnabled) {
   1.755          rasterizerState = rendererData->mainRasterizer;
   1.756      } else {
   1.757          rasterizerState = rendererData->clippedRasterizer;
   1.758 @@ -1940,13 +1998,7 @@
   1.759          ID3D11DeviceContext_RSSetState(rendererData->d3dContext, rasterizerState);
   1.760          rendererData->currentRasterizerState = rasterizerState;
   1.761      }
   1.762 -}
   1.763  
   1.764 -static void
   1.765 -D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
   1.766 -{
   1.767 -    D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
   1.768 -    ID3D11BlendState *blendState = NULL;
   1.769      if (blendMode != SDL_BLENDMODE_NONE) {
   1.770          int i;
   1.771          for (i = 0; i < rendererData->blendModesCount; ++i) {
   1.772 @@ -1967,17 +2019,7 @@
   1.773          ID3D11DeviceContext_OMSetBlendState(rendererData->d3dContext, blendState, 0, 0xFFFFFFFF);
   1.774          rendererData->currentBlendState = blendState;
   1.775      }
   1.776 -}
   1.777  
   1.778 -static void
   1.779 -D3D11_SetPixelShader(SDL_Renderer * renderer,
   1.780 -                     ID3D11PixelShader * shader,
   1.781 -                     int numShaderResources,
   1.782 -                     ID3D11ShaderResourceView ** shaderResources,
   1.783 -                     ID3D11SamplerState * sampler)
   1.784 -{
   1.785 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.786 -    ID3D11ShaderResourceView *shaderResource;
   1.787      if (shader != rendererData->currentShader) {
   1.788          ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0);
   1.789          rendererData->currentShader = shader;
   1.790 @@ -1995,146 +2037,26 @@
   1.791          ID3D11DeviceContext_PSSetSamplers(rendererData->d3dContext, 0, 1, &sampler);
   1.792          rendererData->currentSampler = sampler;
   1.793      }
   1.794 -}
   1.795  
   1.796 -static void
   1.797 -D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
   1.798 -                         D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
   1.799 -                         UINT vertexCount)
   1.800 -{
   1.801 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.802 -
   1.803 -    ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
   1.804 -    ID3D11DeviceContext_Draw(rendererData->d3dContext, vertexCount, 0);
   1.805 -}
   1.806 -
   1.807 -static int
   1.808 -D3D11_RenderDrawPoints(SDL_Renderer * renderer,
   1.809 -                       const SDL_FPoint * points, int count)
   1.810 -{
   1.811 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.812 -    float r, g, b, a;
   1.813 -    VertexPositionColor *vertices;
   1.814 -    int i;
   1.815 -
   1.816 -    r = (float)(renderer->r / 255.0f);
   1.817 -    g = (float)(renderer->g / 255.0f);
   1.818 -    b = (float)(renderer->b / 255.0f);
   1.819 -    a = (float)(renderer->a / 255.0f);
   1.820 -
   1.821 -    vertices = SDL_stack_alloc(VertexPositionColor, count);
   1.822 -    for (i = 0; i < count; ++i) {
   1.823 -        const VertexPositionColor v = { { points[i].x + 0.5f, points[i].y + 0.5f, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
   1.824 -        vertices[i] = v;
   1.825 -    }
   1.826 -
   1.827 -    D3D11_RenderStartDrawOp(renderer);
   1.828 -    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
   1.829 -    if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
   1.830 -        SDL_stack_free(vertices);
   1.831 -        return -1;
   1.832 -    }
   1.833 -
   1.834 -    D3D11_SetPixelShader(
   1.835 -        renderer,
   1.836 -        rendererData->pixelShaders[SHADER_SOLID],
   1.837 -        0,
   1.838 -        NULL,
   1.839 -        NULL);
   1.840 -
   1.841 -    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
   1.842 -    SDL_stack_free(vertices);
   1.843 -    return 0;
   1.844 -}
   1.845 -
   1.846 -static int
   1.847 -D3D11_RenderDrawLines(SDL_Renderer * renderer,
   1.848 -                      const SDL_FPoint * points, int count)
   1.849 -{
   1.850 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.851 -    float r, g, b, a;
   1.852 -    VertexPositionColor *vertices;
   1.853 -    int i;
   1.854 -
   1.855 -    r = (float)(renderer->r / 255.0f);
   1.856 -    g = (float)(renderer->g / 255.0f);
   1.857 -    b = (float)(renderer->b / 255.0f);
   1.858 -    a = (float)(renderer->a / 255.0f);
   1.859 -
   1.860 -    vertices = SDL_stack_alloc(VertexPositionColor, count);
   1.861 -    for (i = 0; i < count; ++i) {
   1.862 -        const VertexPositionColor v = { { points[i].x + 0.5f, points[i].y + 0.5f, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
   1.863 -        vertices[i] = v;
   1.864 -    }
   1.865 -
   1.866 -    D3D11_RenderStartDrawOp(renderer);
   1.867 -    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
   1.868 -    if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
   1.869 -        SDL_stack_free(vertices);
   1.870 -        return -1;
   1.871 -    }
   1.872 -
   1.873 -    D3D11_SetPixelShader(
   1.874 -        renderer,
   1.875 -        rendererData->pixelShaders[SHADER_SOLID],
   1.876 -        0,
   1.877 -        NULL,
   1.878 -        NULL);
   1.879 -
   1.880 -    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
   1.881 -
   1.882 -    if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) {
   1.883 -        ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
   1.884 -        ID3D11DeviceContext_Draw(rendererData->d3dContext, 1, count - 1);
   1.885 -    }
   1.886 -
   1.887 -    SDL_stack_free(vertices);
   1.888 -    return 0;
   1.889 -}
   1.890 -
   1.891 -static int
   1.892 -D3D11_RenderFillRects(SDL_Renderer * renderer,
   1.893 -                      const SDL_FRect * rects, int count)
   1.894 -{
   1.895 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.896 -    float r, g, b, a;
   1.897 -    int i;
   1.898 -
   1.899 -    r = (float)(renderer->r / 255.0f);
   1.900 -    g = (float)(renderer->g / 255.0f);
   1.901 -    b = (float)(renderer->b / 255.0f);
   1.902 -    a = (float)(renderer->a / 255.0f);
   1.903 -
   1.904 -    for (i = 0; i < count; ++i) {
   1.905 -        VertexPositionColor vertices[] = {
   1.906 -            { { rects[i].x, rects[i].y, 0.0f },                             { 0.0f, 0.0f}, {r, g, b, a} },
   1.907 -            { { rects[i].x, rects[i].y + rects[i].h, 0.0f },                { 0.0f, 0.0f }, { r, g, b, a } },
   1.908 -            { { rects[i].x + rects[i].w, rects[i].y, 0.0f },                { 0.0f, 0.0f }, { r, g, b, a } },
   1.909 -            { { rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f },   { 0.0f, 0.0f }, { r, g, b, a } },
   1.910 -        };
   1.911 -
   1.912 -        D3D11_RenderStartDrawOp(renderer);
   1.913 -        D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
   1.914 -        if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
   1.915 -            return -1;
   1.916 -        }
   1.917 -
   1.918 -        D3D11_SetPixelShader(
   1.919 -            renderer,
   1.920 -            rendererData->pixelShaders[SHADER_SOLID],
   1.921 +    if (SDL_memcmp(&data->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)) != 0) {
   1.922 +        SDL_memcpy(&data->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix));
   1.923 +        ID3D11DeviceContext_UpdateSubresource(data->d3dContext,
   1.924 +            (ID3D11Resource *)data->vertexShaderConstants,
   1.925              0,
   1.926              NULL,
   1.927 -            NULL);
   1.928 -
   1.929 -        D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, SDL_arraysize(vertices));
   1.930 +            &data->vertexShaderConstantsData,
   1.931 +            0,
   1.932 +            0
   1.933 +            );
   1.934      }
   1.935  
   1.936      return 0;
   1.937  }
   1.938  
   1.939  static int
   1.940 -D3D11_RenderSetupSampler(SDL_Renderer * renderer, SDL_Texture * texture)
   1.941 +D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
   1.942  {
   1.943 +    SDL_Texture *texture = cmd->data.draw.texture;
   1.944      D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.945      D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
   1.946      ID3D11SamplerState *textureSampler;
   1.947 @@ -2172,12 +2094,8 @@
   1.948              return SDL_SetError("Unsupported YUV conversion mode");
   1.949          }
   1.950  
   1.951 -        D3D11_SetPixelShader(
   1.952 -            renderer,
   1.953 -            rendererData->pixelShaders[shader],
   1.954 -            SDL_arraysize(shaderResources),
   1.955 -            shaderResources,
   1.956 -            textureSampler);
   1.957 +        return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[shader],
   1.958 +                                  SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
   1.959  
   1.960      } else if (textureData->nv12) {
   1.961          ID3D11ShaderResourceView *shaderResources[] = {
   1.962 @@ -2200,194 +2118,162 @@
   1.963              return SDL_SetError("Unsupported YUV conversion mode");
   1.964          }
   1.965  
   1.966 -        D3D11_SetPixelShader(
   1.967 -            renderer,
   1.968 -            rendererData->pixelShaders[shader],
   1.969 -            SDL_arraysize(shaderResources),
   1.970 -            shaderResources,
   1.971 -            textureSampler);
   1.972 +        return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[shader],
   1.973 +                                  SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
   1.974  
   1.975 -    } else {
   1.976 -        D3D11_SetPixelShader(
   1.977 -            renderer,
   1.978 -            rendererData->pixelShaders[SHADER_RGB],
   1.979 -            1,
   1.980 -            &textureData->mainTextureResourceView,
   1.981 -            textureSampler);
   1.982 +    }
   1.983 +
   1.984 +    return D3D11_SetDrawState(renderer, cmd,  renderer, rendererData->pixelShaders[SHADER_RGB],
   1.985 +                              1, &textureData->mainTextureResourceView, textureSampler, matrix);
   1.986 +}
   1.987 +
   1.988 +static void
   1.989 +D3D11_DrawPrimitives(SDL_Renderer * renderer, D3D11_PRIMITIVE_TOPOLOGY primitiveTopology, const UINT vertexStart, const UINT vertexCount)
   1.990 +{
   1.991 +    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
   1.992 +    ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
   1.993 +    ID3D11DeviceContext_Draw(rendererData->d3dContext, vertexCount, vertexStart);
   1.994 +}
   1.995 +
   1.996 +static int
   1.997 +D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
   1.998 +{
   1.999 +    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  1.1000 +    const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
  1.1001 +    size_t i;
  1.1002 +
  1.1003 +    if (rendererData->currentViewportRotation != viewportRotation) {
  1.1004 +        rendererData->currentViewportRotation = viewportRotation;
  1.1005 +        rendererData->viewportDirty = SDL_TRUE;
  1.1006 +    }
  1.1007 +
  1.1008 +    if (D3D11_UpdateVertexBuffer(renderer, vertices, vertsize) < 0) {
  1.1009 +        return -1;
  1.1010 +    }
  1.1011 +
  1.1012 +    while (cmd) {
  1.1013 +        switch (cmd->command) {
  1.1014 +            case SDL_RENDERCMD_SETDRAWCOLOR: {
  1.1015 +                break;  /* this isn't currently used in this render backend. */
  1.1016 +            }
  1.1017 +
  1.1018 +            case SDL_RENDERCMD_SETVIEWPORT: {
  1.1019 +                SDL_Rect *viewport = &rendererData->currentViewport;
  1.1020 +                if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
  1.1021 +                    SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
  1.1022 +                    data->drawstate.viewportDirty = SDL_TRUE;
  1.1023 +                }
  1.1024 +                break;
  1.1025 +            }
  1.1026 +
  1.1027 +            case SDL_RENDERCMD_SETCLIPRECT: {
  1.1028 +                const SDL_Rect *rect = &cmd->data.cliprect.rect;
  1.1029 +                if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) {
  1.1030 +                    rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled;
  1.1031 +                    rendererData->cliprectDirty = SDL_TRUE;
  1.1032 +                }
  1.1033 +                if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)) != 0) {
  1.1034 +                    SDL_memcpy(&rendererData->currentCliprect, rect, sizeof (SDL_Rect));
  1.1035 +                    rendererData->cliprectDirty = SDL_TRUE;
  1.1036 +                }
  1.1037 +                break;
  1.1038 +            }
  1.1039 +
  1.1040 +            case SDL_RENDERCMD_CLEAR: {
  1.1041 +                const float colorRGBA[] = {
  1.1042 +                    (cmd->data.color.r / 255.0f),
  1.1043 +                    (cmd->data.color.g / 255.0f),
  1.1044 +                    (cmd->data.color.b / 255.0f),
  1.1045 +                    (cmd->data.color.a / 255.0f)
  1.1046 +                };
  1.1047 +                ID3D11DeviceContext_ClearRenderTargetView(data->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), colorRGBA);
  1.1048 +                break;
  1.1049 +            }
  1.1050 +
  1.1051 +            case SDL_RENDERCMD_DRAW_POINTS: {
  1.1052 +                const size_t count = cmd->data.draw.count;
  1.1053 +                const size_t first = cmd->data.draw.first;
  1.1054 +                const size_t start = first / sizeof (VertexPositionColor);
  1.1055 +                D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
  1.1056 +                D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start, count);
  1.1057 +                break;
  1.1058 +            }
  1.1059 +
  1.1060 +            case SDL_RENDERCMD_DRAW_LINES: {
  1.1061 +                const size_t count = cmd->data.draw.count;
  1.1062 +                const size_t first = cmd->data.draw.first;
  1.1063 +                const size_t start = first / sizeof (VertexPositionColor);
  1.1064 +                const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first);
  1.1065 +                D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
  1.1066 +                D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, start, count);
  1.1067 +                if (verts[0].x != verts[count - 1].x || verts[0].y != verts[count - 1].y) {
  1.1068 +                    D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start + (count-1), 1);
  1.1069 +                }
  1.1070 +                break;
  1.1071 +            }
  1.1072 +
  1.1073 +            case SDL_RENDERCMD_FILL_RECTS: {
  1.1074 +                const size_t count = cmd->data.draw.count;
  1.1075 +                const size_t first = cmd->data.draw.first;
  1.1076 +                const size_t start = first / sizeof (VertexPositionColor);
  1.1077 +                size_t offset = 0;
  1.1078 +                D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
  1.1079 +                for (i = 0; i < count; i++, offset += 4) {
  1.1080 +                    D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start + offset, 4);
  1.1081 +                }
  1.1082 +                break;
  1.1083 +            }
  1.1084 +
  1.1085 +            case SDL_RENDERCMD_COPY: {
  1.1086 +                const size_t first = cmd->data.draw.first;
  1.1087 +                const size_t start = first / sizeof (VertexPositionColor);
  1.1088 +                D3D11_SetCopyState(data, cmd, NULL);
  1.1089 +                D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
  1.1090 +                break;
  1.1091 +            }
  1.1092 +
  1.1093 +            case SDL_RENDERCMD_COPY_EX: {
  1.1094 +                const size_t first = cmd->data.draw.first;
  1.1095 +                const size_t start = first / sizeof (VertexPositionColor);
  1.1096 +                const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first);
  1.1097 +                const Vertex *transvert = verts + 4;
  1.1098 +                const float translatex = transvert->pos.x;
  1.1099 +                const float translatey = transvert->pos.y;
  1.1100 +                const float rotation = transvert->pos.z;
  1.1101 +                const Float4X4 matrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
  1.1102 +                D3D11_SetCopyState(data, cmd, &matrix);
  1.1103 +                D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
  1.1104 +                break;
  1.1105 +            }
  1.1106 +
  1.1107 +            case SDL_RENDERCMD_NO_OP:
  1.1108 +                break;
  1.1109 +        }
  1.1110 +
  1.1111 +        cmd = cmd->next;
  1.1112      }
  1.1113  
  1.1114      return 0;
  1.1115  }
  1.1116  
  1.1117 -static int
  1.1118 -D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  1.1119 -                 const SDL_Rect * srcrect, const SDL_FRect * dstrect)
  1.1120 +
  1.1121 +static void
  1.1122 +D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
  1.1123  {
  1.1124 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  1.1125 -    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  1.1126 -    float minu, maxu, minv, maxv;
  1.1127 -    Float4 color;
  1.1128 -    VertexPositionColor vertices[4];
  1.1129 -
  1.1130 -    D3D11_RenderStartDrawOp(renderer);
  1.1131 -    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
  1.1132 -
  1.1133 -    minu = (float) srcrect->x / texture->w;
  1.1134 -    maxu = (float) (srcrect->x + srcrect->w) / texture->w;
  1.1135 -    minv = (float) srcrect->y / texture->h;
  1.1136 -    maxv = (float) (srcrect->y + srcrect->h) / texture->h;
  1.1137 -
  1.1138 -    color.x = 1.0f;     /* red */
  1.1139 -    color.y = 1.0f;     /* green */
  1.1140 -    color.z = 1.0f;     /* blue */
  1.1141 -    color.w = 1.0f;     /* alpha */
  1.1142 -    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
  1.1143 -        color.x = (float)(texture->r / 255.0f);     /* red */
  1.1144 -        color.y = (float)(texture->g / 255.0f);     /* green */
  1.1145 -        color.z = (float)(texture->b / 255.0f);     /* blue */
  1.1146 -    }
  1.1147 -    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
  1.1148 -        color.w = (float)(texture->a / 255.0f);     /* alpha */
  1.1149 -    }
  1.1150 -
  1.1151 -    vertices[0].pos.x = dstrect->x;
  1.1152 -    vertices[0].pos.y = dstrect->y;
  1.1153 -    vertices[0].pos.z = 0.0f;
  1.1154 -    vertices[0].tex.x = minu;
  1.1155 -    vertices[0].tex.y = minv;
  1.1156 -    vertices[0].color = color;
  1.1157 -
  1.1158 -    vertices[1].pos.x = dstrect->x;
  1.1159 -    vertices[1].pos.y = dstrect->y + dstrect->h;
  1.1160 -    vertices[1].pos.z = 0.0f;
  1.1161 -    vertices[1].tex.x = minu;
  1.1162 -    vertices[1].tex.y = maxv;
  1.1163 -    vertices[1].color = color;
  1.1164 -
  1.1165 -    vertices[2].pos.x = dstrect->x + dstrect->w;
  1.1166 -    vertices[2].pos.y = dstrect->y;
  1.1167 -    vertices[2].pos.z = 0.0f;
  1.1168 -    vertices[2].tex.x = maxu;
  1.1169 -    vertices[2].tex.y = minv;
  1.1170 -    vertices[2].color = color;
  1.1171 -
  1.1172 -    vertices[3].pos.x = dstrect->x + dstrect->w;
  1.1173 -    vertices[3].pos.y = dstrect->y + dstrect->h;
  1.1174 -    vertices[3].pos.z = 0.0f;
  1.1175 -    vertices[3].tex.x = maxu;
  1.1176 -    vertices[3].tex.y = maxv;
  1.1177 -    vertices[3].color = color;
  1.1178 -
  1.1179 -    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
  1.1180 -        return -1;
  1.1181 -    }
  1.1182 -
  1.1183 -    if (D3D11_RenderSetupSampler(renderer, texture) < 0) {
  1.1184 -        return -1;
  1.1185 -    }
  1.1186 -
  1.1187 -    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
  1.1188 -
  1.1189 -    return 0;
  1.1190 +    D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  1.1191 +    ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
  1.1192 +    SAFE_RELEASE(data->mainRenderTargetView);
  1.1193  }
  1.1194  
  1.1195 -static int
  1.1196 -D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
  1.1197 -                   const SDL_Rect * srcrect, const SDL_FRect * dstrect,
  1.1198 -                   const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
  1.1199 +static ID3D11RenderTargetView *
  1.1200 +D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
  1.1201  {
  1.1202 -    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  1.1203 -    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  1.1204 -    float minu, maxu, minv, maxv;
  1.1205 -    Float4 color;
  1.1206 -    Float4X4 modelMatrix;
  1.1207 -    float minx, maxx, miny, maxy;
  1.1208 -    VertexPositionColor vertices[4];
  1.1209 -
  1.1210 -    D3D11_RenderStartDrawOp(renderer);
  1.1211 -    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
  1.1212 -
  1.1213 -    minu = (float) srcrect->x / texture->w;
  1.1214 -    maxu = (float) (srcrect->x + srcrect->w) / texture->w;
  1.1215 -    minv = (float) srcrect->y / texture->h;
  1.1216 -    maxv = (float) (srcrect->y + srcrect->h) / texture->h;
  1.1217 -
  1.1218 -    color.x = 1.0f;     /* red */
  1.1219 -    color.y = 1.0f;     /* green */
  1.1220 -    color.z = 1.0f;     /* blue */
  1.1221 -    color.w = 1.0f;     /* alpha */
  1.1222 -    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
  1.1223 -        color.x = (float)(texture->r / 255.0f);     /* red */
  1.1224 -        color.y = (float)(texture->g / 255.0f);     /* green */
  1.1225 -        color.z = (float)(texture->b / 255.0f);     /* blue */
  1.1226 +    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  1.1227 +    if (data->currentOffscreenRenderTargetView) {
  1.1228 +        return data->currentOffscreenRenderTargetView;
  1.1229 +    } else {
  1.1230 +        return data->mainRenderTargetView;
  1.1231      }
  1.1232 -    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
  1.1233 -        color.w = (float)(texture->a / 255.0f);     /* alpha */
  1.1234 -    }
  1.1235 -
  1.1236 -    if (flip & SDL_FLIP_HORIZONTAL) {
  1.1237 -        float tmp = maxu;
  1.1238 -        maxu = minu;
  1.1239 -        minu = tmp;
  1.1240 -    }
  1.1241 -    if (flip & SDL_FLIP_VERTICAL) {
  1.1242 -        float tmp = maxv;
  1.1243 -        maxv = minv;
  1.1244 -        minv = tmp;
  1.1245 -    }
  1.1246 -
  1.1247 -    modelMatrix = MatrixMultiply(
  1.1248 -            MatrixRotationZ((float)(M_PI * (float) angle / 180.0f)),
  1.1249 -            MatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
  1.1250 -            );
  1.1251 -    D3D11_SetModelMatrix(renderer, &modelMatrix);
  1.1252 -
  1.1253 -    minx = -center->x;
  1.1254 -    maxx = dstrect->w - center->x;
  1.1255 -    miny = -center->y;
  1.1256 -    maxy = dstrect->h - center->y;
  1.1257 -
  1.1258 -    vertices[0].pos.x = minx;
  1.1259 -    vertices[0].pos.y = miny;
  1.1260 -    vertices[0].pos.z = 0.0f;
  1.1261 -    vertices[0].tex.x = minu;
  1.1262 -    vertices[0].tex.y = minv;
  1.1263 -    vertices[0].color = color;
  1.1264 -    
  1.1265 -    vertices[1].pos.x = minx;
  1.1266 -    vertices[1].pos.y = maxy;
  1.1267 -    vertices[1].pos.z = 0.0f;
  1.1268 -    vertices[1].tex.x = minu;
  1.1269 -    vertices[1].tex.y = maxv;
  1.1270 -    vertices[1].color = color;
  1.1271 -    
  1.1272 -    vertices[2].pos.x = maxx;
  1.1273 -    vertices[2].pos.y = miny;
  1.1274 -    vertices[2].pos.z = 0.0f;
  1.1275 -    vertices[2].tex.x = maxu;
  1.1276 -    vertices[2].tex.y = minv;
  1.1277 -    vertices[2].color = color;
  1.1278 -    
  1.1279 -    vertices[3].pos.x = maxx;
  1.1280 -    vertices[3].pos.y = maxy;
  1.1281 -    vertices[3].pos.z = 0.0f;
  1.1282 -    vertices[3].tex.x = maxu;
  1.1283 -    vertices[3].tex.y = maxv;
  1.1284 -    vertices[3].color = color;
  1.1285 -
  1.1286 -    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
  1.1287 -        return -1;
  1.1288 -    }
  1.1289 -
  1.1290 -    if (D3D11_RenderSetupSampler(renderer, texture) < 0) {
  1.1291 -        return -1;
  1.1292 -    }
  1.1293 -
  1.1294 -    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
  1.1295 -
  1.1296 -    D3D11_SetModelMatrix(renderer, NULL);
  1.1297 -
  1.1298 -    return 0;
  1.1299  }
  1.1300  
  1.1301  static int
  1.1302 @@ -2554,6 +2440,108 @@
  1.1303      }
  1.1304  }
  1.1305  
  1.1306 +SDL_Renderer *
  1.1307 +D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
  1.1308 +{
  1.1309 +    SDL_Renderer *renderer;
  1.1310 +    D3D11_RenderData *data;
  1.1311 +
  1.1312 +    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
  1.1313 +    if (!renderer) {
  1.1314 +        SDL_OutOfMemory();
  1.1315 +        return NULL;
  1.1316 +    }
  1.1317 +
  1.1318 +    data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
  1.1319 +    if (!data) {
  1.1320 +        SDL_OutOfMemory();
  1.1321 +        return NULL;
  1.1322 +    }
  1.1323 +
  1.1324 +    renderer->WindowEvent = D3D11_WindowEvent;
  1.1325 +    renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
  1.1326 +    renderer->CreateTexture = D3D11_CreateTexture;
  1.1327 +    renderer->UpdateTexture = D3D11_UpdateTexture;
  1.1328 +    renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
  1.1329 +    renderer->LockTexture = D3D11_LockTexture;
  1.1330 +    renderer->UnlockTexture = D3D11_UnlockTexture;
  1.1331 +    renderer->SetRenderTarget = D3D11_SetRenderTarget;
  1.1332 +    renderer->QueueSetViewport = D3D11_QueueSetViewport;
  1.1333 +    renderer->QueueSetDrawColor = D3D11_QueueSetViewport;  /* SetViewport and SetDrawColor are (currently) no-ops. */
  1.1334 +    renderer->QueueDrawPoints = D3D11_QueueDrawPoints;
  1.1335 +    renderer->QueueDrawLines = D3D11_QueueDrawPoints;  /* lines and points queue vertices the same way. */
  1.1336 +    renderer->QueueFillRects = D3D11_QueueFillRects;
  1.1337 +    renderer->QueueCopy = D3D11_QueueCopy;
  1.1338 +    renderer->QueueCopyEx = D3D11_QueueCopyEx;
  1.1339 +    renderer->RunCommandQueue = D3D11_RunCommandQueue;
  1.1340 +    renderer->RenderReadPixels = D3D11_RenderReadPixels;
  1.1341 +    renderer->RenderPresent = D3D11_RenderPresent;
  1.1342 +    renderer->DestroyTexture = D3D11_DestroyTexture;
  1.1343 +    renderer->DestroyRenderer = D3D11_DestroyRenderer;
  1.1344 +    renderer->info = D3D11_RenderDriver.info;
  1.1345 +    renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
  1.1346 +    renderer->driverdata = data;
  1.1347 +
  1.1348 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
  1.1349 +    /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
  1.1350 +     * Failure to use it seems to either result in:
  1.1351 +     *
  1.1352 +     *  - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
  1.1353 +     *    off (framerate doesn't get capped), but nothing appears on-screen
  1.1354 +     *
  1.1355 +     *  - with the D3D11 debug runtime turned ON, vsync gets automatically
  1.1356 +     *    turned back on, and the following gets output to the debug console:
  1.1357 +     *    
  1.1358 +     *    DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ] 
  1.1359 +     */
  1.1360 +    renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
  1.1361 +#else
  1.1362 +    if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
  1.1363 +        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
  1.1364 +    }
  1.1365 +#endif
  1.1366 +
  1.1367 +    /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
  1.1368 +     * order to give init functions access to the underlying window handle:
  1.1369 +     */
  1.1370 +    renderer->window = window;
  1.1371 +
  1.1372 +    /* Initialize Direct3D resources */
  1.1373 +    if (FAILED(D3D11_CreateDeviceResources(renderer))) {
  1.1374 +        D3D11_DestroyRenderer(renderer);
  1.1375 +        return NULL;
  1.1376 +    }
  1.1377 +    if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
  1.1378 +        D3D11_DestroyRenderer(renderer);
  1.1379 +        return NULL;
  1.1380 +    }
  1.1381 +
  1.1382 +    return renderer;
  1.1383 +}
  1.1384 +
  1.1385 +SDL_RenderDriver D3D11_RenderDriver = {
  1.1386 +    D3D11_CreateRenderer,
  1.1387 +    {
  1.1388 +        "direct3d11",
  1.1389 +        (
  1.1390 +            SDL_RENDERER_ACCELERATED |
  1.1391 +            SDL_RENDERER_PRESENTVSYNC |
  1.1392 +            SDL_RENDERER_TARGETTEXTURE
  1.1393 +        ),                          /* flags.  see SDL_RendererFlags */
  1.1394 +        6,                          /* num_texture_formats */
  1.1395 +        {                           /* texture_formats */
  1.1396 +            SDL_PIXELFORMAT_ARGB8888,
  1.1397 +            SDL_PIXELFORMAT_RGB888,
  1.1398 +            SDL_PIXELFORMAT_YV12,
  1.1399 +            SDL_PIXELFORMAT_IYUV,
  1.1400 +            SDL_PIXELFORMAT_NV12,
  1.1401 +            SDL_PIXELFORMAT_NV21
  1.1402 +        },
  1.1403 +        0,                          /* max_texture_width: will be filled in later */
  1.1404 +        0                           /* max_texture_height: will be filled in later */
  1.1405 +    }
  1.1406 +};
  1.1407 +
  1.1408  #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
  1.1409  
  1.1410  /* vi: set ts=4 sw=4 expandtab: */