WinRT: added support for SDL_HINT_RENDER_SCALE_QUALITY
authorDavid Ludwig <dludwig@pobox.com>
Fri, 01 Nov 2013 22:54:39 -0400
changeset 8540 724af2cd53b8
parent 8539 41885a5f550d
child 8541 0041edb891f3
WinRT: added support for SDL_HINT_RENDER_SCALE_QUALITY
src/render/direct3d11/SDL_render_d3d11.cpp
src/render/direct3d11/SDL_render_d3d11_cpp.h
--- a/src/render/direct3d11/SDL_render_d3d11.cpp	Mon Oct 28 15:52:04 2013 -0400
+++ b/src/render/direct3d11/SDL_render_d3d11.cpp	Fri Nov 01 22:54:39 2013 -0400
@@ -60,6 +60,10 @@
 using namespace Windows::UI::Core;
 #endif
 
+/* Texture sampling types */
+static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_MIP_POINT;
+static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+
 /* Direct3D 11.1 renderer implementation */
 
 static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
@@ -487,10 +491,10 @@
     data->vertexBuffer = nullptr;
 
     //
-    // Create a sampler to use when drawing textures:
+    // Create samplers to use when drawing textures:
     //
     D3D11_SAMPLER_DESC samplerDesc;
-    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+    samplerDesc.Filter = SDL_D3D11_NEAREST_PIXEL_FILTER;
     samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
     samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
     samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
@@ -505,7 +509,17 @@
     samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
     result = data->d3dDevice->CreateSamplerState(
         &samplerDesc,
-        &data->mainSampler
+        &data->nearestPixelSampler
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    samplerDesc.Filter = SDL_D3D11_LINEAR_FILTER;
+    result = data->d3dDevice->CreateSamplerState(
+        &samplerDesc,
+        &data->linearSampler
         );
     if (FAILED(result)) {
         WIN_SetErrorFromHRESULT(__FUNCTION__, result);
@@ -928,6 +942,17 @@
     }
 }
 
+static D3D11_FILTER
+GetScaleQuality(void)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
+    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+        return SDL_D3D11_NEAREST_PIXEL_FILTER;
+    } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
+        return SDL_D3D11_LINEAR_FILTER;
+    }
+}
+
 static int
 D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
@@ -948,6 +973,7 @@
     }
     textureData->pixelFormat = SDL_AllocFormat(texture->format);
     textureData->lockedTexturePosition = XMINT2(0, 0);
+    textureData->scaleMode = GetScaleQuality();
 
     texture->driverdata = textureData;
 
@@ -1621,6 +1647,22 @@
     return 0;
 }
 
+static ID3D11SamplerState *
+D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    switch (textureData->scaleMode) {
+        case SDL_D3D11_NEAREST_PIXEL_FILTER:
+            return rendererData->nearestPixelSampler.Get();
+        case SDL_D3D11_LINEAR_FILTER:
+            return rendererData->linearSampler.Get();
+        default:
+            return NULL;
+    }
+}
+
 static int
 D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
@@ -1659,11 +1701,12 @@
         return -1;
     }
 
+    ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture);
     D3D11_SetPixelShader(
         renderer,
         rendererData->texturePixelShader.Get(),
         textureData->mainTextureResourceView.Get(),
-        rendererData->mainSampler.Get());
+        textureSampler);
 
     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
 
@@ -1733,11 +1776,12 @@
         return -1;
     }
 
+    ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture);
     D3D11_SetPixelShader(
         renderer,
         rendererData->texturePixelShader.Get(),
         textureData->mainTextureResourceView.Get(),
-        rendererData->mainSampler.Get());
+        textureSampler);
 
     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
 
--- a/src/render/direct3d11/SDL_render_d3d11_cpp.h	Mon Oct 28 15:52:04 2013 -0400
+++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h	Fri Nov 01 22:54:39 2013 -0400
@@ -47,7 +47,8 @@
     Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeBlend;
     Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeAdd;
     Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeMod;
-    Microsoft::WRL::ComPtr<ID3D11SamplerState> mainSampler;
+    Microsoft::WRL::ComPtr<ID3D11SamplerState> nearestPixelSampler;
+    Microsoft::WRL::ComPtr<ID3D11SamplerState> linearSampler;
     Microsoft::WRL::ComPtr<ID3D11RasterizerState> mainRasterizer;
     D3D_FEATURE_LEVEL featureLevel;
 
@@ -72,6 +73,7 @@
     SDL_PixelFormat * pixelFormat;
     Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
     DirectX::XMINT2 lockedTexturePosition;
+    D3D11_FILTER scaleMode;
 } D3D11_TextureData;
 
 struct VertexPositionColor