Commit 9616e583 by apatrick@chromium.org

Merge no-flip-rows r1142 to trunk.

Review URL: https://codereview.appspot.com/6304052 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1162 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e6357c0e
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1156 #define BUILD_REVISION 1162
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -219,25 +219,11 @@ void OutputHLSL::header() ...@@ -219,25 +219,11 @@ void OutputHLSL::header()
out << uniforms; out << uniforms;
out << "\n"; out << "\n";
// The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored
// according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0)
// is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D
// convention, the Y coordinate passed to these functions is adjusted to compensate.
//
// The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0].
//
// The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3
// case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0].
//
// For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the
// +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the
// +Y and -Y faces everywhere else throughout the code.
if (mUsesTexture2D) if (mUsesTexture2D)
{ {
out << "float4 gl_texture2D(sampler2D s, float2 t)\n" out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
"{\n" "{\n"
" return tex2D(s, float2(t.x, 1 - t.y));\n" " return tex2D(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -246,7 +232,7 @@ void OutputHLSL::header() ...@@ -246,7 +232,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n" out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x, 1 - t.y, 0, bias));\n" " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -255,12 +241,12 @@ void OutputHLSL::header() ...@@ -255,12 +241,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
"{\n" "{\n"
" return tex2Dproj(s, float4(t.x, t.z - t.y, 0, t.z));\n" " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProj(sampler2D s, float4 t)\n" "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
"{\n" "{\n"
" return tex2Dproj(s, float4(t.x, t.w - t.y, t.z, t.w));\n" " return tex2Dproj(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -269,12 +255,12 @@ void OutputHLSL::header() ...@@ -269,12 +255,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n" out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x / t.z, 1 - (t.y / t.z), 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n" "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n"
"{\n" "{\n"
" return tex2Dbias(s, float4(t.x / t.w, 1 - (t.y / t.w), 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -283,7 +269,7 @@ void OutputHLSL::header() ...@@ -283,7 +269,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
"{\n" "{\n"
" return texCUBE(s, float3(t.x, -t.y, t.z));\n" " return texCUBE(s, t);\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -292,7 +278,7 @@ void OutputHLSL::header() ...@@ -292,7 +278,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n" out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n"
"{\n" "{\n"
" return texCUBEbias(s, float4(t.x, -t.y, t.z, bias));\n" " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -303,7 +289,7 @@ void OutputHLSL::header() ...@@ -303,7 +289,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n" out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n" " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -312,7 +298,7 @@ void OutputHLSL::header() ...@@ -312,7 +298,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n" out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n" " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -321,12 +307,12 @@ void OutputHLSL::header() ...@@ -321,12 +307,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n" out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProjLod(sampler2D s, float4 t)\n" "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -335,12 +321,12 @@ void OutputHLSL::header() ...@@ -335,12 +321,12 @@ void OutputHLSL::header()
{ {
out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n" out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
"}\n" "}\n"
"\n" "\n"
"float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n" "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n"
"{\n" "{\n"
" return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n" " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -349,7 +335,7 @@ void OutputHLSL::header() ...@@ -349,7 +335,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n" out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n"
"{\n" "{\n"
" return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n" " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -358,7 +344,7 @@ void OutputHLSL::header() ...@@ -358,7 +344,7 @@ void OutputHLSL::header()
{ {
out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n" out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n"
"{\n" "{\n"
" return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n" " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -1232,7 +1218,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) ...@@ -1232,7 +1218,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
} }
else else
{ {
outputTriplet(visit, "(-ddy(", "", "))"); outputTriplet(visit, "ddy(", "", ")");
} }
break; break;
case EOpFwidth: case EOpFwidth:
......
...@@ -43,6 +43,7 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos ...@@ -43,6 +43,7 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{ {
mSwapChain = NULL; mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL; mDepthStencil = NULL;
mRenderTarget = NULL; mRenderTarget = NULL;
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
...@@ -64,6 +65,7 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL ...@@ -64,6 +65,7 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
: mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
{ {
mSwapChain = NULL; mSwapChain = NULL;
mBackBuffer = NULL;
mDepthStencil = NULL; mDepthStencil = NULL;
mRenderTarget = NULL; mRenderTarget = NULL;
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
...@@ -121,6 +123,12 @@ void Surface::release() ...@@ -121,6 +123,12 @@ void Surface::release()
mSwapChain = NULL; mSwapChain = NULL;
} }
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mDepthStencil) if (mDepthStencil)
{ {
mDepthStencil->Release(); mDepthStencil->Release();
...@@ -144,6 +152,8 @@ void Surface::release() ...@@ -144,6 +152,8 @@ void Surface::release()
mTexture->releaseTexImage(); mTexture->releaseTexImage();
mTexture = NULL; mTexture = NULL;
} }
mShareHandle = NULL;
} }
bool Surface::resetSwapChain() bool Surface::resetSwapChain()
...@@ -174,57 +184,13 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -174,57 +184,13 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
return false; return false;
} }
IDirect3DSurface9* preservedRenderTarget = NULL;
if (mPostSubBufferSupported && mRenderTarget)
{
preservedRenderTarget = mRenderTarget;
preservedRenderTarget->AddRef();
}
// Evict all non-render target textures to system memory and release all resources // Evict all non-render target textures to system memory and release all resources
// before reallocating them to free up as much video memory as possible. // before reallocating them to free up as much video memory as possible.
device->EvictManagedResources(); device->EvictManagedResources();
release();
D3DPRESENT_PARAMETERS presentParameters = {0}; D3DPRESENT_PARAMETERS presentParameters = {0};
HRESULT result; HRESULT result;
bool useFlipEx = (getComparableOSVersion() >= versionWindows7) && mDisplay->isD3d9ExDevice();
// FlipEx causes unseemly stretching when resizing windows AND when one
// draws outside of the WM_PAINT callback. While this is seldom a problem in
// single process applications, it is particuarly noticeable in multiprocess
// applications. Therefore, if the creator process of our window is not in
// the current process, disable use of FlipEx.
DWORD windowPID;
GetWindowThreadProcessId(mWindow, &windowPID);
if (windowPID != GetCurrentProcessId())
{
useFlipEx = false;
}
// Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the
// device format or back buffer format is not 32-bit.
HDC deviceContext = GetDC(0);
int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL);
ReleaseDC(0, deviceContext);
if (mConfig->mBufferSize != 32 || deviceFormatBits != 32)
{
useFlipEx = false;
}
// D3DSWAPEFFECT_FLIPEX is always VSYNCed
if (mSwapInterval == 0)
{
useFlipEx = false;
}
// D3DSWAPEFFECT_FLIPEX does not preserve the back buffer.
if (mPostSubBufferSupported)
{
useFlipEx = false;
}
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.
// We do this because DirectX docs are a bit vague whether to set this to 1 // We do this because DirectX docs are a bit vague whether to set this to 1
...@@ -239,42 +205,51 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -239,42 +205,51 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
presentParameters.PresentationInterval = mPresentInterval; presentParameters.PresentationInterval = mPresentInterval;
// Use flipEx on Win7 or greater. presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
if(useFlipEx)
presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX;
else
presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD;
presentParameters.Windowed = TRUE; presentParameters.Windowed = TRUE;
presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferWidth = backbufferWidth;
presentParameters.BackBufferHeight = backbufferHeight; presentParameters.BackBufferHeight = backbufferHeight;
if (mWindow) // Release specific resources to free up memory for the new render target, while the
// old render target still exists for the purpose of preserving its contents.
if (mSwapChain)
{ {
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); mSwapChain->Release();
} else { mSwapChain = NULL;
HANDLE *pShareHandle = NULL;
if (mDisplay->shareHandleSupported()) {
pShareHandle = &mShareHandle;
} }
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, if (mBackBuffer)
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); {
mBackBuffer->Release();
mBackBuffer = NULL;
} }
if (FAILED(result)) if (mOffscreenTexture)
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); mOffscreenTexture->Release();
mOffscreenTexture = NULL;
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); }
release();
if (mDepthStencil)
{
mDepthStencil->Release();
mDepthStencil = NULL;
}
if (preservedRenderTarget) mShareHandle = NULL;
HANDLE *pShareHandle = NULL;
if (!mWindow && mDisplay->shareHandleSupported())
{ {
preservedRenderTarget->Release(); pShareHandle = &mShareHandle;
preservedRenderTarget = NULL;
} }
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
if (FAILED(result))
{
ERR("Could not create offscreen texture: %08lX", result);
release();
if(isDeviceLostError(result)) if(isDeviceLostError(result))
{ {
mDisplay->notifyDeviceLost(); mDisplay->notifyDeviceLost();
...@@ -286,20 +261,12 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -286,20 +261,12 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
} }
} }
if (mWindow) IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
{
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
if (!preservedRenderTarget)
{
InvalidateRect(mWindow, NULL, FALSE);
}
}
else
{
mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
}
if (preservedRenderTarget) result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
ASSERT(SUCCEEDED(result));
if (oldRenderTarget)
{ {
RECT rect = RECT rect =
{ {
...@@ -318,10 +285,37 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -318,10 +285,37 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
} }
mDisplay->endScene(); mDisplay->endScene();
device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
preservedRenderTarget->Release(); result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
preservedRenderTarget = NULL; ASSERT(SUCCEEDED(result));
oldRenderTarget->Release();
}
if (mWindow)
{
result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
} }
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
...@@ -329,7 +323,6 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -329,7 +323,6 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
}
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -337,8 +330,18 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -337,8 +330,18 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
release(); release();
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false); return error(EGL_BAD_ALLOC, false);
} }
}
}
mWidth = presentParameters.BackBufferWidth; mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight; mHeight = presentParameters.BackBufferHeight;
...@@ -347,6 +350,113 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -347,6 +350,113 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
return true; return true;
} }
bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
return true;
}
if (x + width > mWidth)
{
width = mWidth - x;
}
if (y + height > mHeight)
{
height = mHeight - y;
}
if (width == 0 || height == 0)
{
return true;
}
IDirect3DDevice9 *device = mDisplay->getDevice();
// Disable all pipeline operations
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetRenderTarget(0, mBackBuffer);
device->SetDepthStencilSurface(NULL);
device->SetTexture(0, mOffscreenTexture);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
device->SetViewport(&viewport);
float x1 = x - 0.5f;
float y1 = (mHeight - y - height) - 0.5f;
float x2 = (x + width) - 0.5f;
float y2 = (mHeight - y) - 0.5f;
float u1 = x / float(mWidth);
float v1 = y / float(mHeight);
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
{x2, y1, 0.0f, 1.0f, u2, v2},
{x2, y2, 0.0f, 1.0f, u2, v1},
{x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
mDisplay->endScene();
device->SetTexture(0, NULL);
RECT rect =
{
x, mHeight - y - height,
x + width, mHeight - y
};
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
if (context)
{
context->markAllStateDirty();
}
if (isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
return error(EGL_BAD_ALLOC, false);
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
return true;
}
HWND Surface::getWindowHandle() HWND Surface::getWindowHandle()
{ {
return mWindow; return mWindow;
...@@ -467,87 +577,18 @@ DWORD Surface::convertInterval(EGLint interval) ...@@ -467,87 +577,18 @@ DWORD Surface::convertInterval(EGLint interval)
bool Surface::swap() bool Surface::swap()
{ {
if (mSwapChain) return swapRect(0, 0, mWidth, mHeight);
{
mDisplay->endScene();
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(EGL_BAD_ALLOC, false);
}
if (isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
}
return true;
} }
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{ {
if (x < 0 || y < 0 || width < 0 || height < 0)
{
return error(EGL_BAD_PARAMETER, false);
}
if (!mPostSubBufferSupported) if (!mPostSubBufferSupported)
{ {
// Spec is not clear about how this should be handled. // Spec is not clear about how this should be handled.
return true; return true;
} }
if (mSwapChain) return swapRect(x, y, width, height);
{
mDisplay->endScene();
RECT rect =
{
x, mHeight - y - height,
x + width, mHeight - y
};
if (rect.right > mWidth)
{
rect.right = mWidth;
}
if (rect.bottom > mHeight)
{
rect.bottom = mHeight;
}
if (rect.left == rect.right || rect.top == rect.bottom)
{
return true;
}
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
return error(EGL_BAD_ALLOC, false);
}
if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED)
{
return error(EGL_CONTEXT_LOST, false);
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
}
return true;
} }
EGLint Surface::getWidth() const EGLint Surface::getWidth() const
......
...@@ -69,6 +69,7 @@ private: ...@@ -69,6 +69,7 @@ private:
Display *const mDisplay; Display *const mDisplay;
IDirect3DSwapChain9 *mSwapChain; IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mDepthStencil; IDirect3DSurface9 *mDepthStencil;
IDirect3DSurface9* mRenderTarget; IDirect3DSurface9* mRenderTarget;
IDirect3DTexture9* mOffscreenTexture; IDirect3DTexture9* mOffscreenTexture;
...@@ -78,6 +79,7 @@ private: ...@@ -78,6 +79,7 @@ private:
void subclassWindow(); void subclassWindow();
void unsubclassWindow(); void unsubclassWindow();
bool resetSwapChain(int backbufferWidth, int backbufferHeight); bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
static DWORD convertInterval(EGLint interval); static DWORD convertInterval(EGLint interval);
const HWND mWindow; // Window that the surface is created for. const HWND mWindow; // Window that the surface is created for.
......
...@@ -1108,6 +1108,11 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi ...@@ -1108,6 +1108,11 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
try try
{ {
if (x < 0 || y < 0 || width < 0 || height < 0)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
......
...@@ -1955,11 +1955,10 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1955,11 +1955,10 @@ bool Context::applyRenderTarget(bool ignoreViewport)
} }
else else
{ {
RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, mRenderTargetDesc.Height); viewport.X = clamp(mState.viewportX, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
viewport.X = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); viewport.Y = clamp(mState.viewportY, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); viewport.Width = clamp(mState.viewportWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X));
viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X)); viewport.Height = clamp(mState.viewportHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y));
viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y));
viewport.MinZ = zNear; viewport.MinZ = zNear;
viewport.MaxZ = zFar; viewport.MaxZ = zFar;
} }
...@@ -1981,11 +1980,11 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1981,11 +1980,11 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{ {
if (mState.scissorTest) if (mState.scissorTest)
{ {
RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, mRenderTargetDesc.Height); RECT rect;
rect.left = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); rect.left = clamp(mState.scissorX, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); rect.top = clamp(mState.scissorY, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); rect.right = clamp(mState.scissorX + mState.scissorWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); rect.bottom = clamp(mState.scissorY + mState.scissorHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
mDevice->SetScissorRect(&rect); mDevice->SetScissorRect(&rect);
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
} }
...@@ -2006,10 +2005,9 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -2006,10 +2005,9 @@ bool Context::applyRenderTarget(bool ignoreViewport)
GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height}; GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height};
programBinary->setUniform2fv(halfPixelSize, 1, xy); programBinary->setUniform2fv(halfPixelSize, 1, xy);
// These values are used for computing gl_FragCoord in Program::linkVaryings(). The approach depends on Shader Model 3.0 support. // These values are used for computing gl_FragCoord in Program::linkVaryings().
GLint coord = programBinary->getDxCoordLocation(); GLint coord = programBinary->getDxCoordLocation();
float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f; GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f,
GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h,
(float)mState.viewportX + mState.viewportWidth / 2.0f, (float)mState.viewportX + mState.viewportWidth / 2.0f,
(float)mState.viewportY + mState.viewportHeight / 2.0f}; (float)mState.viewportY + mState.viewportHeight / 2.0f};
programBinary->setUniform4fv(coord, 1, whxy); programBinary->setUniform4fv(coord, 1, whxy);
...@@ -2035,10 +2033,8 @@ void Context::applyState(GLenum drawMode) ...@@ -2035,10 +2033,8 @@ void Context::applyState(GLenum drawMode)
Framebuffer *framebufferObject = getDrawFramebuffer(); Framebuffer *framebufferObject = getDrawFramebuffer();
GLenum adjustedFrontFace = adjustWinding(mState.frontFace);
GLint frontCCW = programBinary->getDxFrontCCWLocation(); GLint frontCCW = programBinary->getDxFrontCCWLocation();
GLint ccw = (adjustedFrontFace == GL_CCW); GLint ccw = (mState.frontFace == GL_CCW);
programBinary->setUniform1iv(frontCCW, 1, &ccw); programBinary->setUniform1iv(frontCCW, 1, &ccw);
GLint pointsOrLines = programBinary->getDxPointsOrLinesLocation(); GLint pointsOrLines = programBinary->getDxPointsOrLinesLocation();
...@@ -2057,7 +2053,7 @@ void Context::applyState(GLenum drawMode) ...@@ -2057,7 +2053,7 @@ void Context::applyState(GLenum drawMode)
{ {
if (mState.cullFace) if (mState.cullFace)
{ {
mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace)); mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace));
} }
else else
{ {
...@@ -2157,32 +2153,32 @@ void Context::applyState(GLenum drawMode) ...@@ -2157,32 +2153,32 @@ void Context::applyState(GLenum drawMode)
gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilFunc)); es2dx::ConvertComparison(mState.stencilFunc));
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilFail)); es2dx::ConvertStencilOp(mState.stencilFail));
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilPassDepthFail)); es2dx::ConvertStencilOp(mState.stencilPassDepthFail));
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilPassDepthPass)); es2dx::ConvertStencilOp(mState.stencilPassDepthPass));
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilBackFunc)); es2dx::ConvertComparison(mState.stencilBackFunc));
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilBackFail)); es2dx::ConvertStencilOp(mState.stencilBackFail));
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail)); es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail));
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass)); es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass));
} }
else else
...@@ -2475,7 +2471,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -2475,7 +2471,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
HRESULT result; HRESULT result;
IDirect3DSurface9 *systemSurface = NULL; IDirect3DSurface9 *systemSurface = NULL;
bool directToPixels = getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() && bool directToPixels = !getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() &&
x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height &&
desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
if (directToPixels) if (directToPixels)
...@@ -2528,13 +2524,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -2528,13 +2524,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
return; return;
} }
D3DLOCKED_RECT lock; RECT rect;
RECT rect = transformPixelRect(x, y, width, height, desc.Height); rect.left = clamp(x, 0L, static_cast<LONG>(desc.Width));
rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width)); rect.top = clamp(y, 0L, static_cast<LONG>(desc.Height));
rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height)); rect.right = clamp(x + width, 0L, static_cast<LONG>(desc.Width));
rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width)); rect.bottom = clamp(y + height, 0L, static_cast<LONG>(desc.Height));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height));
D3DLOCKED_RECT lock;
result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
if (FAILED(result)) if (FAILED(result))
...@@ -2552,13 +2548,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -2552,13 +2548,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
int inputPitch; int inputPitch;
if (getPackReverseRowOrder()) if (getPackReverseRowOrder())
{ {
source = (unsigned char*)lock.pBits; source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
inputPitch = lock.Pitch; inputPitch = -lock.Pitch;
} }
else else
{ {
source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); source = (unsigned char*)lock.pBits;
inputPitch = -lock.Pitch; inputPitch = lock.Pitch;
} }
for (int j = 0; j < rect.bottom - rect.top; j++) for (int j = 0; j < rect.bottom - rect.top; j++)
...@@ -3879,17 +3875,17 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3879,17 +3875,17 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (srcY0 < srcY1) if (srcY0 < srcY1)
{ {
sourceRect.top = readBufferHeight - srcY1; sourceRect.bottom = srcY1;
destRect.top = drawBufferHeight - dstY1; destRect.bottom = dstY1;
sourceRect.bottom = readBufferHeight - srcY0; sourceRect.top = srcY0;
destRect.bottom = drawBufferHeight - dstY0; destRect.top = dstY0;
} }
else else
{ {
sourceRect.top = readBufferHeight - srcY0; sourceRect.bottom = srcY0;
destRect.top = drawBufferHeight - dstY0; destRect.bottom = dstY0;
sourceRect.bottom = readBufferHeight - srcY1; sourceRect.top = srcY1;
destRect.bottom = drawBufferHeight - dstY1; destRect.top = dstY1;
} }
RECT sourceScissoredRect = sourceRect; RECT sourceScissoredRect = sourceRect;
......
...@@ -281,7 +281,7 @@ class Context ...@@ -281,7 +281,7 @@ class Context
void makeCurrent(egl::Display *display, egl::Surface *surface); void makeCurrent(egl::Display *display, egl::Surface *surface);
void markAllStateDirty(); virtual void markAllStateDirty();
void markDxUniformsDirty(); void markDxUniformsDirty();
virtual void markContextLost(); virtual void markContextLost();
......
...@@ -1391,7 +1391,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1391,7 +1391,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
"\n" "\n"
" VS_OUTPUT output;\n" " VS_OUTPUT output;\n"
" output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n" " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
" output.gl_Position.y = gl_Position.y - dx_HalfPixelSize.y * gl_Position.w;\n" " output.gl_Position.y = -(gl_Position.y + dx_HalfPixelSize.y * gl_Position.w);\n"
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n"; " output.gl_Position.w = gl_Position.w;\n";
...@@ -1524,15 +1524,14 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1524,15 +1524,14 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (sm3) if (sm3)
{ {
// dx_Coord.y contains the render target height. See Context::applyRenderTarget()
pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
" gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n"; " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
} }
else else
{ {
// dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget() // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget()
pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n" pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
" gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n"; " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n";
} }
pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
...@@ -1541,7 +1540,8 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1541,7 +1540,8 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (fragmentShader->mUsesPointCoord && sm3) if (fragmentShader->mUsesPointCoord && sm3)
{ {
pixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n"; pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n";
pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
} }
if (fragmentShader->mUsesFrontFacing) if (fragmentShader->mUsesFrontFacing)
......
...@@ -291,7 +291,11 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y ...@@ -291,7 +291,11 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
if (sourceSurface && sourceSurface != destSurface) if (sourceSurface && sourceSurface != destSurface)
{ {
RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight); RECT rect;
rect.left = xoffset;
rect.top = yoffset;
rect.right = xoffset + width;
rect.bottom = yoffset + height;
if (mD3DPool == D3DPOOL_MANAGED) if (mD3DPool == D3DPOOL_MANAGED)
{ {
...@@ -309,11 +313,15 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y ...@@ -309,11 +313,15 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
} }
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle at locked.pBits with locked.Pitch bytes in between each line. // into the target pixel rectangle.
void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input) GLint unpackAlignment, const void *input)
{ {
RECT lockRect = transformPixelRect(xoffset, yoffset, width, height, mHeight); RECT lockRect =
{
xoffset, yoffset,
xoffset + width, yoffset + height
};
D3DLOCKED_RECT locked; D3DLOCKED_RECT locked;
HRESULT result = lock(&locked, &lockRect); HRESULT result = lock(&locked, &lockRect);
...@@ -322,8 +330,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height ...@@ -322,8 +330,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
return; return;
} }
GLsizei inputPitch = -ComputePitch(width, mFormat, type, unpackAlignment); GLsizei inputPitch = ComputePitch(width, mFormat, type, unpackAlignment);
input = ((char*)input) - inputPitch * (height - 1);
switch (type) switch (type)
{ {
...@@ -908,7 +915,10 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi ...@@ -908,7 +915,10 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
ASSERT(xoffset % 4 == 0); ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0); ASSERT(yoffset % 4 == 0);
RECT lockRect = transformPixelRect(xoffset, yoffset, width, height, mHeight); RECT lockRect = {
xoffset, yoffset,
xoffset + width, yoffset + height
};
D3DLOCKED_RECT locked; D3DLOCKED_RECT locked;
HRESULT result = lock(&locked, &lockRect); HRESULT result = lock(&locked, &lockRect);
...@@ -917,278 +927,17 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi ...@@ -917,278 +927,17 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
return; return;
} }
GLsizei inputPitch = -ComputeCompressedPitch(width, mFormat);
GLsizei inputSize = ComputeCompressedSize(width, height, mFormat); GLsizei inputSize = ComputeCompressedSize(width, height, mFormat);
input = ((char*)input) + inputSize + inputPitch; GLsizei inputPitch = ComputeCompressedPitch(width, mFormat);
int rows = inputSize / inputPitch;
switch (getD3DFormat()) for (int i = 0; i < rows; ++i)
{ {
case D3DFMT_DXT1: memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
loadDXT1Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case D3DFMT_DXT3:
loadDXT3Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case D3DFMT_DXT5:
loadDXT5Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
} }
unlock(); unlock();
} }
static void FlipCopyDXT1BlockFull(const unsigned int* source, unsigned int* dest) {
// A DXT1 block layout is:
// [0-1] color0.
// [2-3] color1.
// [4-7] color bitmap, 2 bits per pixel.
// So each of the 4-7 bytes represents one line, flipping a block is just
// flipping those bytes.
// First 32-bits is two RGB565 colors shared by tile and does not need to be modified.
dest[0] = source[0];
// Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors. All rows should be flipped.
dest[1] = (source[1] >> 24) |
((source[1] << 8) & 0x00FF0000) |
((source[1] >> 8) & 0x0000FF00) |
(source[1] << 24);
}
// Flips the first 2 lines of a DXT1 block in the y direction.
static void FlipCopyDXT1BlockHalf(const unsigned int* source, unsigned int* dest) {
// See layout above.
dest[0] = source[0];
dest[1] = ((source[1] << 8) & 0x0000FF00) |
((source[1] >> 8) & 0x000000FF);
}
// Flips a full DXT3 block in the y direction.
static void FlipCopyDXT3BlockFull(const unsigned int* source, unsigned int* dest) {
// A DXT3 block layout is:
// [0-7] alpha bitmap, 4 bits per pixel.
// [8-15] a DXT1 block.
// First and Second 32 bits are 4bit per pixel alpha and need to be flipped.
dest[0] = (source[1] >> 16) | (source[1] << 16);
dest[1] = (source[0] >> 16) | (source[0] << 16);
// And flip the DXT1 block using the above function.
FlipCopyDXT1BlockFull(source + 2, dest + 2);
}
// Flips the first 2 lines of a DXT3 block in the y direction.
static void FlipCopyDXT3BlockHalf(const unsigned int* source, unsigned int* dest) {
// See layout above.
dest[0] = (source[1] >> 16) | (source[1] << 16);
FlipCopyDXT1BlockHalf(source + 2, dest + 2);
}
// Flips a full DXT5 block in the y direction.
static void FlipCopyDXT5BlockFull(const unsigned int* source, unsigned int* dest) {
// A DXT5 block layout is:
// [0] alpha0.
// [1] alpha1.
// [2-7] alpha bitmap, 3 bits per pixel.
// [8-15] a DXT1 block.
// The alpha bitmap doesn't easily map lines to bytes, so we have to
// interpret it correctly. Extracted from
// http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt :
//
// The 6 "bits" bytes of the block are decoded into one 48-bit integer:
//
// bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
// 256 * (bits_4 + 256 * bits_5))))
//
// bits is a 48-bit unsigned integer, from which a three-bit control code
// is extracted for a texel at location (x,y) in the block using:
//
// code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
//
// where bit 47 is the most significant and bit 0 is the least
// significant bit.
const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source));
unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest));
unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]);
unsigned int line_2_3 = sourceBytes[5] + 256 * (sourceBytes[6] + 256 * sourceBytes[7]);
// swap lines 0 and 1 in line_0_1.
unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
((line_0_1 & 0xfff000) >> 12);
// swap lines 2 and 3 in line_2_3.
unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) |
((line_2_3 & 0xfff000) >> 12);
destBytes[0] = sourceBytes[0];
destBytes[1] = sourceBytes[1];
destBytes[2] = line_3_2 & 0xff;
destBytes[3] = (line_3_2 & 0xff00) >> 8;
destBytes[4] = (line_3_2 & 0xff0000) >> 16;
destBytes[5] = line_1_0 & 0xff;
destBytes[6] = (line_1_0 & 0xff00) >> 8;
destBytes[7] = (line_1_0 & 0xff0000) >> 16;
// And flip the DXT1 block using the above function.
FlipCopyDXT1BlockFull(source + 2, dest + 2);
}
// Flips the first 2 lines of a DXT5 block in the y direction.
static void FlipCopyDXT5BlockHalf(const unsigned int* source, unsigned int* dest) {
// See layout above.
const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source));
unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest));
unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]);
unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
((line_0_1 & 0xfff000) >> 12);
destBytes[0] = sourceBytes[0];
destBytes[1] = sourceBytes[1];
destBytes[2] = line_1_0 & 0xff;
destBytes[3] = (line_1_0 & 0xff00) >> 8;
destBytes[4] = (line_1_0 & 0xff0000) >> 16;
FlipCopyDXT1BlockHalf(source + 2, dest + 2);
}
void Image::loadDXT1Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 8 == 0);
ASSERT(outputPitch % 8 == 0);
const unsigned int *source = reinterpret_cast<const unsigned int*>(input);
unsigned int *dest = reinterpret_cast<unsigned int*>(output);
// Round width up in case it is less than 4.
int blocksAcross = (width + 3) / 4;
int intsAcross = blocksAcross * 2;
switch (height)
{
case 1:
for (int x = 0; x < intsAcross; x += 2)
{
// just copy the block
dest[x] = source[x];
dest[x + 1] = source[x + 1];
}
break;
case 2:
for (int x = 0; x < intsAcross; x += 2)
{
FlipCopyDXT1BlockHalf(source + x, dest + x);
}
break;
default:
ASSERT(height % 4 == 0);
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 2)
{
FlipCopyDXT1BlockFull(source + x, dest + x);
}
}
break;
}
}
void Image::loadDXT3Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 16 == 0);
ASSERT(outputPitch % 16 == 0);
const unsigned int *source = reinterpret_cast<const unsigned int*>(input);
unsigned int *dest = reinterpret_cast<unsigned int*>(output);
// Round width up in case it is less than 4.
int blocksAcross = (width + 3) / 4;
int intsAcross = blocksAcross * 4;
switch (height)
{
case 1:
for (int x = 0; x < intsAcross; x += 4)
{
// just copy the block
dest[x] = source[x];
dest[x + 1] = source[x + 1];
dest[x + 2] = source[x + 2];
dest[x + 3] = source[x + 3];
}
break;
case 2:
for (int x = 0; x < intsAcross; x += 4)
{
FlipCopyDXT3BlockHalf(source + x, dest + x);
}
break;
default:
ASSERT(height % 4 == 0);
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 4)
{
FlipCopyDXT3BlockFull(source + x, dest + x);
}
}
break;
}
}
void Image::loadDXT5Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(width % 4 == 0 || width == 2 || width == 1);
ASSERT(inputPitch % 16 == 0);
ASSERT(outputPitch % 16 == 0);
const unsigned int *source = reinterpret_cast<const unsigned int*>(input);
unsigned int *dest = reinterpret_cast<unsigned int*>(output);
// Round width up in case it is less than 4.
int blocksAcross = (width + 3) / 4;
int intsAcross = blocksAcross * 4;
switch (height)
{
case 1:
for (int x = 0; x < intsAcross; x += 4)
{
// just copy the block
dest[x] = source[x];
dest[x + 1] = source[x + 1];
dest[x + 2] = source[x + 2];
dest[x + 3] = source[x + 3];
}
break;
case 2:
for (int x = 0; x < intsAcross; x += 4)
{
FlipCopyDXT5BlockHalf(source + x, dest + x);
}
break;
default:
ASSERT(height % 4 == 0);
for (int y = 0; y < height / 4; ++y)
{
const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
for (int x = 0; x < intsAcross; x += 4)
{
FlipCopyDXT5BlockFull(source + x, dest + x);
}
}
break;
}
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget) void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
{ {
...@@ -1214,9 +963,8 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, ...@@ -1214,9 +963,8 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
RECT sourceRect = transformPixelRect(x, y, width, height, description.Height); RECT sourceRect = {x, y, x + width, y + height};
int destYOffset = transformPixelYOffset(yoffset, height, mHeight); RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height};
if (isRenderableFormat()) if (isRenderableFormat())
{ {
...@@ -1971,19 +1719,17 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1971,19 +1719,17 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
if (width != 0 && height != 0 && level < levelCount()) if (width != 0 && height != 0 && level < levelCount())
{ {
RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); RECT sourceRect;
sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); sourceRect.left = x;
sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); sourceRect.right = x + width;
sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); sourceRect.top = y;
sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); sourceRect.bottom = y + height;
GLint destYOffset = transformPixelYOffset(0, height, mImageArray[level].getHeight());
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level);
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -2023,19 +1769,18 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -2023,19 +1769,18 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
if (level < levelCount()) if (level < levelCount())
{ {
RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); RECT sourceRect;
sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); sourceRect.left = x;
sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); sourceRect.right = x + width;
sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); sourceRect.top = y;
sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); sourceRect.bottom = y + height;
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[level].getHeight());
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level);
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, destYOffset, dest); getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, yoffset, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -2923,19 +2668,17 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2923,19 +2668,17 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
if (width > 0 && level < levelCount()) if (width > 0 && level < levelCount())
{ {
RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); RECT sourceRect;
sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); sourceRect.left = x;
sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); sourceRect.right = x + width;
sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); sourceRect.top = y;
sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); sourceRect.bottom = y + height;
GLint destYOffset = transformPixelYOffset(0, height, mImageArray[faceindex][level].getWidth());
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level);
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -2979,19 +2722,17 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2979,19 +2722,17 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
if (level < levelCount()) if (level < levelCount())
{ {
RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); RECT sourceRect;
sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); sourceRect.left = x;
sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); sourceRect.right = x + width;
sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); sourceRect.top = y;
sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); sourceRect.bottom = y + height;
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[faceindex][level].getWidth());
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level);
if (dest) if (dest)
{ {
getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, destYOffset, dest); getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, yoffset, dest);
dest->Release(); dest->Release();
} }
} }
......
...@@ -113,12 +113,6 @@ class Image ...@@ -113,12 +113,6 @@ class Image
int inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input); const void *input);
void loadDXT1Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT3Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT5Data(GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget); void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
......
...@@ -70,26 +70,6 @@ inline unsigned int unorm(float x) ...@@ -70,26 +70,6 @@ inline unsigned int unorm(float x)
} }
} }
inline RECT transformPixelRect(GLint x, GLint y, GLint w, GLint h, GLint surfaceHeight)
{
RECT rect = {x,
surfaceHeight - y - h,
x + w,
surfaceHeight - y};
return rect;
}
inline int transformPixelYOffset(GLint yoffset, GLint h, GLint surfaceHeight)
{
return surfaceHeight - yoffset - h;
}
inline GLenum adjustWinding(GLenum winding)
{
ASSERT(winding == GL_CW || winding == GL_CCW);
return winding == GL_CW ? GL_CCW : GL_CW;
}
inline bool supportsSSE2() inline bool supportsSSE2()
{ {
static bool checked = false; static bool checked = false;
......
...@@ -612,9 +612,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) ...@@ -612,9 +612,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
{ {
D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
// Map a cube map texture target to the corresponding D3D surface index. Note that the
// Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions
// are negated in the pixel shader.
switch (cubeFace) switch (cubeFace)
{ {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
...@@ -624,10 +621,10 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) ...@@ -624,10 +621,10 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
face = D3DCUBEMAP_FACE_NEGATIVE_X; face = D3DCUBEMAP_FACE_NEGATIVE_X;
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
face = D3DCUBEMAP_FACE_NEGATIVE_Y; face = D3DCUBEMAP_FACE_POSITIVE_Y;
break; break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
face = D3DCUBEMAP_FACE_POSITIVE_Y; face = D3DCUBEMAP_FACE_NEGATIVE_Y;
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
face = D3DCUBEMAP_FACE_POSITIVE_Z; face = D3DCUBEMAP_FACE_POSITIVE_Z;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment