Commit b31f532d by apatrick@chromium.org

All surfaces follow D3D Y convention, i.e. (0, 0) is "top-left" rather than GL's…

All surfaces follow D3D Y convention, i.e. (0, 0) is "top-left" rather than GL's "bottom-left". This eliminates the need to flip the default FBO to the D3D convention using additional blits when presenting and reduces VRAM usage for redundant window sized surfaces. I took out the gl_Position.y flip from the vertex shader so FBOs are rendered according to D3D conventions. Texture lookups are flipped on Y to compensate. Cube map +Y and -Y faces are swapped. Y is now flipped in various other places, including uploading and reading back texture data from / to system memory, functions that take pixel space coordinates, winding order for culling, the implementation of ddy, the calculation of gl_Position and gl_FragCoord in fragment shaders and the flipping of compressed texture tiles. Review URL: http://codereview.appspot.com/3265041 git-svn-id: https://angleproject.googlecode.com/svn/trunk@536 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 3bd9d90f
...@@ -196,11 +196,25 @@ void OutputHLSL::header() ...@@ -196,11 +196,25 @@ 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, t);\n" " return tex2D(s, float2(t.x, 1 - t.y));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -209,7 +223,7 @@ void OutputHLSL::header() ...@@ -209,7 +223,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, t.y, 0, bias));\n" " return tex2Dbias(s, float4(t.x, 1 - t.y, 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -218,12 +232,12 @@ void OutputHLSL::header() ...@@ -218,12 +232,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.y, 0, t.z));\n" " return tex2Dproj(s, float4(t.x, t.z - 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, t);\n" " return tex2Dproj(s, float4(t.x, t.w - t.y, t.z, t.w));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -232,12 +246,12 @@ void OutputHLSL::header() ...@@ -232,12 +246,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, t.y / t.z, 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.z, 1 - (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, t.y / t.w, 0, bias));\n" " return tex2Dbias(s, float4(t.x / t.w, 1 - (t.y / t.w), 0, bias));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -246,7 +260,7 @@ void OutputHLSL::header() ...@@ -246,7 +260,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, t);\n" " return texCUBE(s, float3(t.x, -t.y, t.z));\n"
"}\n" "}\n"
"\n"; "\n";
} }
...@@ -255,7 +269,7 @@ void OutputHLSL::header() ...@@ -255,7 +269,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";
} }
...@@ -968,7 +982,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) ...@@ -968,7 +982,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpLength: outputTriplet(visit, "length(", "", ")"); break; case EOpLength: outputTriplet(visit, "length(", "", ")"); break;
case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break;
case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break; case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break;
case EOpDFdy: outputTriplet(visit, "ddy(", "", ")"); break; case EOpDFdy: outputTriplet(visit, "(-ddy(", "", "))"); break;
case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break; case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break;
case EOpAny: outputTriplet(visit, "any(", "", ")"); break; case EOpAny: outputTriplet(visit, "any(", "", ")"); break;
case EOpAll: outputTriplet(visit, "all(", "", ")"); break; case EOpAll: outputTriplet(visit, "all(", "", ")"); break;
......
...@@ -24,10 +24,7 @@ Surface::Surface(Display *display, const Config *config, HWND window) ...@@ -24,10 +24,7 @@ Surface::Surface(Display *display, const Config *config, HWND window)
{ {
mSwapChain = NULL; mSwapChain = NULL;
mDepthStencil = NULL; mDepthStencil = NULL;
mBackBuffer = NULL; mRenderTarget = NULL;
mFlipTexture = NULL;
mFlipState = NULL;
mPreFlipState = NULL;
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER; mRenderBuffer = EGL_BACK_BUFFER;
...@@ -53,34 +50,16 @@ void Surface::release() ...@@ -53,34 +50,16 @@ void Surface::release()
mSwapChain = NULL; mSwapChain = NULL;
} }
if (mBackBuffer)
{
mBackBuffer->Release();
mBackBuffer = NULL;
}
if (mDepthStencil) if (mDepthStencil)
{ {
mDepthStencil->Release(); mDepthStencil->Release();
mDepthStencil = NULL; mDepthStencil = NULL;
} }
if (mFlipTexture) if (mRenderTarget)
{
mFlipTexture->Release();
mFlipTexture = NULL;
}
if (mFlipState)
{
mFlipState->Release();
mFlipState = NULL;
}
if (mPreFlipState)
{ {
mPreFlipState->Release(); mRenderTarget->Release();
mPreFlipState = NULL; mRenderTarget = NULL;
} }
} }
...@@ -152,30 +131,13 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -152,30 +131,13 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
return error(EGL_BAD_ALLOC); return error(EGL_BAD_ALLOC);
} }
ASSERT(SUCCEEDED(result)); mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
ERR("Could not create flip texture for new swap chain: %08lX", result);
release();
return error(EGL_BAD_ALLOC);
}
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
mWidth = presentParameters.BackBufferWidth; mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight; mHeight = presentParameters.BackBufferHeight;
mPresentIntervalDirty = false; mPresentIntervalDirty = false;
InvalidateRect(mWindow, NULL, FALSE); InvalidateRect(mWindow, NULL, FALSE);
// The flip state block recorded mFlipTexture so it is now invalid.
releaseRecordedState(device);
} }
HWND Surface::getWindowHandle() HWND Surface::getWindowHandle()
...@@ -183,132 +145,7 @@ HWND Surface::getWindowHandle() ...@@ -183,132 +145,7 @@ HWND Surface::getWindowHandle()
return mWindow; return mWindow;
} }
void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
{
// 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);
// Just sample the texture
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
device->SetViewport(&viewport);
}
void Surface::applyFlipState(IDirect3DDevice9 *device)
{
HRESULT hr;
if (mFlipState == NULL)
{
// Create two state blocks both recording the states that are changed when swapping.
// mPreFlipState will record the original state each entry.
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
writeRecordableFlipState(device);
hr = device->EndStateBlock(&mPreFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
if (SUCCEEDED(hr))
{
mPreFlipState->Capture();
}
// mFlipState will record the state for the swap operation.
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
writeRecordableFlipState(device);
hr = device->EndStateBlock(&mFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
if (FAILED(hr))
{
mFlipState = NULL;
mPreFlipState->Release();
mPreFlipState = NULL;
}
else
{
hr = mFlipState->Apply();
ASSERT(SUCCEEDED(hr));
}
}
else
{
hr = mPreFlipState->Capture();
ASSERT(SUCCEEDED(hr));
hr = mFlipState->Apply();
ASSERT(SUCCEEDED(hr));
}
device->GetRenderTarget(0, &mPreFlipBackBuffer);
device->GetDepthStencilSurface(&mPreFlipDepthStencil);
device->SetRenderTarget(0, mBackBuffer);
device->SetDepthStencilSurface(NULL);
}
void Surface::restoreState(IDirect3DDevice9 *device)
{
device->SetRenderTarget(0, mPreFlipBackBuffer);
device->SetDepthStencilSurface(mPreFlipDepthStencil);
if (mPreFlipBackBuffer)
{
mPreFlipBackBuffer->Release();
mPreFlipBackBuffer = NULL;
}
if (mPreFlipDepthStencil)
{
mPreFlipDepthStencil->Release();
mPreFlipDepthStencil = NULL;
}
mPreFlipState->Apply();
}
// On the next flip, this will cause the state to be recorded from scratch.
// In particular we need to do this if the flip texture changes.
void Surface::releaseRecordedState(IDirect3DDevice9 *device)
{
if (mFlipState)
{
mFlipState->Release();
mFlipState = NULL;
}
if (mPreFlipState)
{
mPreFlipState->Release();
mPreFlipState = NULL;
}
}
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
...@@ -407,25 +244,6 @@ bool Surface::swap() ...@@ -407,25 +244,6 @@ bool Surface::swap()
{ {
if (mSwapChain) if (mSwapChain)
{ {
IDirect3DDevice9 *device = mDisplay->getDevice();
applyFlipState(device);
device->SetTexture(0, mFlipTexture);
// Render the texture upside down into the back buffer
// Texcoords are chosen to flip the renderTarget about its Y axis.
float w = static_cast<float>(getWidth());
float h = static_cast<float>(getHeight());
float quad[4][6] = {{0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
{w - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
{w - 0.5f, h - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
{0 - 0.5f, h - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
restoreState(device);
mDisplay->endScene(); mDisplay->endScene();
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
...@@ -460,14 +278,12 @@ EGLint Surface::getHeight() const ...@@ -460,14 +278,12 @@ EGLint Surface::getHeight() const
IDirect3DSurface9 *Surface::getRenderTarget() IDirect3DSurface9 *Surface::getRenderTarget()
{ {
IDirect3DSurface9 *textureSurface = NULL; if (mRenderTarget)
if (mFlipTexture)
{ {
mFlipTexture->GetSurfaceLevel(0, &textureSurface); mRenderTarget->AddRef();
} }
return textureSurface; return mRenderTarget;
} }
IDirect3DSurface9 *Surface::getDepthStencil() IDirect3DSurface9 *Surface::getDepthStencil()
......
...@@ -49,24 +49,14 @@ private: ...@@ -49,24 +49,14 @@ private:
Display *const mDisplay; Display *const mDisplay;
IDirect3DSwapChain9 *mSwapChain; IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mDepthStencil; IDirect3DSurface9 *mDepthStencil;
IDirect3DTexture9 *mFlipTexture; IDirect3DSurface9* mRenderTarget;
void subclassWindow(); void subclassWindow();
void unsubclassWindow(); void unsubclassWindow();
void resetSwapChain(int backbufferWidth, int backbufferHeight); void resetSwapChain(int backbufferWidth, int backbufferHeight);
static DWORD convertInterval(EGLint interval); static DWORD convertInterval(EGLint interval);
void applyFlipState(IDirect3DDevice9 *device);
void restoreState(IDirect3DDevice9 *device);
void writeRecordableFlipState(IDirect3DDevice9 *device);
void releaseRecordedState(IDirect3DDevice9 *device);
IDirect3DStateBlock9 *mFlipState;
IDirect3DStateBlock9 *mPreFlipState;
IDirect3DSurface9 *mPreFlipBackBuffer;
IDirect3DSurface9 *mPreFlipDepthStencil;
const HWND mWindow; // Window that the surface is created for. const HWND mWindow; // Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
const egl::Config *mConfig; // EGL config surface was created with const egl::Config *mConfig; // EGL config surface was created with
......
...@@ -1647,10 +1647,11 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1647,10 +1647,11 @@ bool Context::applyRenderTarget(bool ignoreViewport)
} }
else else
{ {
viewport.X = std::max(mState.viewportX, 0); RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, desc.Height);
viewport.Y = std::max(mState.viewportY, 0); viewport.X = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
viewport.Width = std::min(mState.viewportWidth, (int)desc.Width - (int)viewport.X); viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
viewport.Height = std::min(mState.viewportHeight, (int)desc.Height - (int)viewport.Y); viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(desc.Width) - static_cast<LONG>(viewport.X));
viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(desc.Height) - static_cast<LONG>(viewport.Y));
viewport.MinZ = zNear; viewport.MinZ = zNear;
viewport.MaxZ = zFar; viewport.MaxZ = zFar;
} }
...@@ -1666,12 +1667,11 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1666,12 +1667,11 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{ {
if (mState.scissorTest) if (mState.scissorTest)
{ {
RECT rect = {mState.scissorX, RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, desc.Height);
mState.scissorY, rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
mState.scissorX + mState.scissorWidth, rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
mState.scissorY + mState.scissorHeight}; rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width));
rect.right = std::min(static_cast<UINT>(rect.right), desc.Width); rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height));
rect.bottom = std::min(static_cast<UINT>(rect.bottom), desc.Height);
device->SetScissorRect(&rect); device->SetScissorRect(&rect);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
} }
...@@ -1688,7 +1688,7 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1688,7 +1688,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation(); GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation();
GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height}; GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height};
programObject->setUniform2fv(halfPixelSize, 1, xy); programObject->setUniform2fv(halfPixelSize, 1, xy);
GLint viewport = programObject->getDxViewportLocation(); GLint viewport = programObject->getDxViewportLocation();
...@@ -1715,21 +1715,23 @@ void Context::applyState(GLenum drawMode) ...@@ -1715,21 +1715,23 @@ void Context::applyState(GLenum drawMode)
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
Framebuffer *framebufferObject = getDrawFramebuffer();
GLenum adjustedFrontFace = adjustWinding(mState.frontFace);
GLint frontCCW = programObject->getDxFrontCCWLocation(); GLint frontCCW = programObject->getDxFrontCCWLocation();
GLint ccw = (mState.frontFace == GL_CCW); GLint ccw = (adjustedFrontFace == GL_CCW);
programObject->setUniform1iv(frontCCW, 1, &ccw); programObject->setUniform1iv(frontCCW, 1, &ccw);
GLint pointsOrLines = programObject->getDxPointsOrLinesLocation(); GLint pointsOrLines = programObject->getDxPointsOrLinesLocation();
GLint alwaysFront = !isTriangleMode(drawMode); GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront); programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
Framebuffer *framebufferObject = getDrawFramebuffer();
if (mCullStateDirty || mFrontFaceDirty) if (mCullStateDirty || mFrontFaceDirty)
{ {
if (mState.cullFace) if (mState.cullFace)
{ {
device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace)); device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace));
} }
else else
{ {
...@@ -1824,32 +1826,32 @@ void Context::applyState(GLenum drawMode) ...@@ -1824,32 +1826,32 @@ void Context::applyState(GLenum drawMode)
gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilFunc)); es2dx::ConvertComparison(mState.stencilFunc));
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilFail)); es2dx::ConvertStencilOp(mState.stencilFail));
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilPassDepthFail)); es2dx::ConvertStencilOp(mState.stencilPassDepthFail));
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilPassDepthPass)); es2dx::ConvertStencilOp(mState.stencilPassDepthPass));
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilBackFunc)); es2dx::ConvertComparison(mState.stencilBackFunc));
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilBackFail)); es2dx::ConvertStencilOp(mState.stencilBackFail));
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail)); es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail));
device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass)); es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass));
} }
else else
...@@ -2126,10 +2128,11 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2126,10 +2128,11 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
} }
D3DLOCKED_RECT lock; D3DLOCKED_RECT lock;
RECT rect = {std::max(x, 0), RECT rect = transformPixelRect(x, y, width, height, desc.Height);
std::max(y, 0), rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
std::min(x + width, (int)desc.Width), rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
std::min(y + height, (int)desc.Height)}; rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height));
result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
...@@ -2141,10 +2144,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2141,10 +2144,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
return; // No sensible error to generate return; // No sensible error to generate
} }
unsigned char *source = (unsigned char*)lock.pBits; unsigned char *source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
unsigned char *dest = (unsigned char*)pixels; unsigned char *dest = (unsigned char*)pixels;
unsigned short *dest16 = (unsigned short*)pixels; unsigned short *dest16 = (unsigned short*)pixels;
int inputPitch = -lock.Pitch;
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
for (int j = 0; j < rect.bottom - rect.top; j++) for (int j = 0; j < rect.bottom - rect.top; j++)
...@@ -2157,7 +2160,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2157,7 +2160,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
// an RGBA source buffer. Note that buffers with no // an RGBA source buffer. Note that buffers with no
// alpha go through the slow path below. // alpha go through the slow path below.
memcpy(dest + j * outputPitch, memcpy(dest + j * outputPitch,
source + j * lock.Pitch, source + j * inputPitch,
(rect.right - rect.left) * 4); (rect.right - rect.left) * 4);
continue; continue;
} }
...@@ -2173,7 +2176,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2173,7 +2176,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
{ {
case D3DFMT_R5G6B5: case D3DFMT_R5G6B5:
{ {
unsigned short rgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch); unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
a = 1.0f; a = 1.0f;
b = (rgb & 0x001F) * (1.0f / 0x001F); b = (rgb & 0x001F) * (1.0f / 0x001F);
...@@ -2183,7 +2186,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2183,7 +2186,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
break; break;
case D3DFMT_A1R5G5B5: case D3DFMT_A1R5G5B5:
{ {
unsigned short argb = *(unsigned short*)(source + 2 * i + j * lock.Pitch); unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
a = (argb & 0x8000) ? 1.0f : 0.0f; a = (argb & 0x8000) ? 1.0f : 0.0f;
b = (argb & 0x001F) * (1.0f / 0x001F); b = (argb & 0x001F) * (1.0f / 0x001F);
...@@ -2193,7 +2196,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2193,7 +2196,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
break; break;
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
{ {
unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = (argb & 0xFF000000) * (1.0f / 0xFF000000); a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
b = (argb & 0x000000FF) * (1.0f / 0x000000FF); b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
...@@ -2203,7 +2206,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2203,7 +2206,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
break; break;
case D3DFMT_X8R8G8B8: case D3DFMT_X8R8G8B8:
{ {
unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = 1.0f; a = 1.0f;
b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
...@@ -2213,7 +2216,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2213,7 +2216,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
break; break;
case D3DFMT_A2R10G10B10: case D3DFMT_A2R10G10B10:
{ {
unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = (argb & 0xC0000000) * (1.0f / 0xC0000000); a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
b = (argb & 0x000003FF) * (1.0f / 0x000003FF); b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
...@@ -2224,10 +2227,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2224,10 +2227,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
case D3DFMT_A32B32G32R32F: case D3DFMT_A32B32G32R32F:
{ {
// float formats in D3D are stored rgba, rather than the other way round // float formats in D3D are stored rgba, rather than the other way round
r = *((float*)(source + 16 * i + j * lock.Pitch) + 0); r = *((float*)(source + 16 * i + j * inputPitch) + 0);
g = *((float*)(source + 16 * i + j * lock.Pitch) + 1); g = *((float*)(source + 16 * i + j * inputPitch) + 1);
b = *((float*)(source + 16 * i + j * lock.Pitch) + 2); b = *((float*)(source + 16 * i + j * inputPitch) + 2);
a = *((float*)(source + 16 * i + j * lock.Pitch) + 3); a = *((float*)(source + 16 * i + j * inputPitch) + 3);
} }
break; break;
case D3DFMT_A16B16G16R16F: case D3DFMT_A16B16G16R16F:
...@@ -2235,7 +2238,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum ...@@ -2235,7 +2238,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
// float formats in D3D are stored rgba, rather than the other way round // float formats in D3D are stored rgba, rather than the other way round
float abgr[4]; float abgr[4];
D3DXFloat16To32Array(abgr, (D3DXFLOAT16*)(source + 8 * i + j * lock.Pitch), 4); D3DXFloat16To32Array(abgr, (D3DXFLOAT16*)(source + 8 * i + j * inputPitch), 4);
a = abgr[3]; a = abgr[3];
b = abgr[2]; b = abgr[2];
...@@ -3295,6 +3298,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3295,6 +3298,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth();
int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight();
int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth();
int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight();
RECT sourceRect; RECT sourceRect;
RECT destRect; RECT destRect;
...@@ -3313,21 +3321,19 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3313,21 +3321,19 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
destRect.right = dstX0; destRect.right = dstX0;
} }
// Arguments to StretchRect must be in D3D-style (0-top) coordinates, so we must
// flip our Y-values here
if (srcY0 < srcY1) if (srcY0 < srcY1)
{ {
sourceRect.bottom = srcY1; sourceRect.top = readBufferHeight - srcY1;
destRect.bottom = dstY1; destRect.top = drawBufferHeight - dstY1;
sourceRect.top = srcY0; sourceRect.bottom = readBufferHeight - srcY0;
destRect.top = dstY0; destRect.bottom = drawBufferHeight - dstY0;
} }
else else
{ {
sourceRect.bottom = srcY0; sourceRect.top = readBufferHeight - srcY0;
destRect.bottom = dstY0; destRect.top = drawBufferHeight - dstY0;
sourceRect.top = srcY1; sourceRect.bottom = readBufferHeight - srcY1;
destRect.top = dstY1; destRect.bottom = drawBufferHeight - dstY1;
} }
RECT sourceScissoredRect = sourceRect; RECT sourceScissoredRect = sourceRect;
...@@ -3382,11 +3388,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3382,11 +3388,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
destTrimmedRect.left += xDiff; destTrimmedRect.left += xDiff;
} }
int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth();
int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight();
int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth();
int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight();
if (sourceTrimmedRect.right > readBufferWidth) if (sourceTrimmedRect.right > readBufferWidth)
{ {
int xDiff = sourceTrimmedRect.right - readBufferWidth; int xDiff = sourceTrimmedRect.right - readBufferWidth;
......
...@@ -1272,7 +1272,7 @@ bool Program::linkVaryings() ...@@ -1272,7 +1272,7 @@ bool Program::linkVaryings()
"\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";
...@@ -1404,10 +1404,10 @@ bool Program::linkVaryings() ...@@ -1404,10 +1404,10 @@ bool Program::linkVaryings()
mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
if (sm3) { if (sm3) {
mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n" mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n"
" gl_FragCoord.y = input.dx_VPos.y;\n"; " gl_FragCoord.y = 2.0 * dx_Viewport.y - input.dx_VPos.y;\n";
} else { } else {
mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n" mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
" gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"; " gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n";
} }
mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n"; " gl_FragCoord.w = rhw;\n";
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "libGLESv2/mathutil.h" #include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h" #include "libGLESv2/utilities.h"
#include "libGLESv2/Blit.h" #include "libGLESv2/Blit.h"
#include "libGLESv2/Framebuffer.h"
namespace gl namespace gl
{ {
...@@ -246,7 +247,8 @@ D3DFORMAT Texture::selectFormat(GLenum format, GLenum type) ...@@ -246,7 +247,8 @@ D3DFORMAT Texture::selectFormat(GLenum format, GLenum type)
void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, size_t outputPitch, void *output, D3DSURFACE_DESC *description) const GLint unpackAlignment, const void *input, size_t outputPitch, void *output, D3DSURFACE_DESC *description) const
{ {
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment); GLsizei inputPitch = -ComputePitch(width, format, type, unpackAlignment);
input = ((char*)input) - inputPitch * (height - 1);
switch (type) switch (type)
{ {
...@@ -350,7 +352,7 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei ...@@ -350,7 +352,7 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
} }
void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned char *source = NULL; const unsigned char *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -370,7 +372,7 @@ void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GL ...@@ -370,7 +372,7 @@ void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GL
} }
void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const float *source = NULL; const float *source = NULL;
float *dest = NULL; float *dest = NULL;
...@@ -390,7 +392,7 @@ void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei widt ...@@ -390,7 +392,7 @@ void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei widt
} }
void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned short *dest = NULL; unsigned short *dest = NULL;
...@@ -410,7 +412,7 @@ void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei ...@@ -410,7 +412,7 @@ void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei
} }
void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{ {
const int destBytesPerPixel = native? 1: 4; const int destBytesPerPixel = native? 1: 4;
const unsigned char *source = NULL; const unsigned char *source = NULL;
...@@ -439,7 +441,7 @@ void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width ...@@ -439,7 +441,7 @@ void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width
} }
void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const float *source = NULL; const float *source = NULL;
float *dest = NULL; float *dest = NULL;
...@@ -459,7 +461,7 @@ void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei ...@@ -459,7 +461,7 @@ void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei
} }
void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned short *dest = NULL; unsigned short *dest = NULL;
...@@ -479,7 +481,7 @@ void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsi ...@@ -479,7 +481,7 @@ void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsi
} }
void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{ {
const int destBytesPerPixel = native? 2: 4; const int destBytesPerPixel = native? 2: 4;
const unsigned char *source = NULL; const unsigned char *source = NULL;
...@@ -508,7 +510,7 @@ void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei ...@@ -508,7 +510,7 @@ void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei
} }
void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const float *source = NULL; const float *source = NULL;
float *dest = NULL; float *dest = NULL;
...@@ -528,7 +530,7 @@ void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLs ...@@ -528,7 +530,7 @@ void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLs
} }
void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned short *dest = NULL; unsigned short *dest = NULL;
...@@ -548,7 +550,7 @@ void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, ...@@ -548,7 +550,7 @@ void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset,
} }
void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned char *source = NULL; const unsigned char *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -568,7 +570,7 @@ void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, ...@@ -568,7 +570,7 @@ void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width,
} }
void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -589,7 +591,7 @@ void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, G ...@@ -589,7 +591,7 @@ void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, G
} }
void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const float *source = NULL; const float *source = NULL;
float *dest = NULL; float *dest = NULL;
...@@ -609,7 +611,7 @@ void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, ...@@ -609,7 +611,7 @@ void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width,
} }
void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned short *dest = NULL; unsigned short *dest = NULL;
...@@ -629,7 +631,7 @@ void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei wi ...@@ -629,7 +631,7 @@ void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei wi
} }
void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned char *source = NULL; const unsigned char *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -649,7 +651,7 @@ void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width ...@@ -649,7 +651,7 @@ void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width
} }
void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -670,7 +672,7 @@ void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, ...@@ -670,7 +672,7 @@ void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width,
} }
void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned short *source = NULL; const unsigned short *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -691,7 +693,7 @@ void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, ...@@ -691,7 +693,7 @@ void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width,
} }
void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const float *source = NULL; const float *source = NULL;
float *dest = NULL; float *dest = NULL;
...@@ -705,7 +707,7 @@ void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width ...@@ -705,7 +707,7 @@ void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width
} }
void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned char *source = NULL; const unsigned char *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -719,7 +721,7 @@ void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei w ...@@ -719,7 +721,7 @@ void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei w
} }
void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const int inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
const unsigned char *source = NULL; const unsigned char *source = NULL;
unsigned char *dest = NULL; unsigned char *dest = NULL;
...@@ -732,6 +734,67 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs ...@@ -732,6 +734,67 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs
} }
} }
void Texture::loadCompressedImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const
{
ASSERT(xoffset % 4 == 0);
ASSERT(yoffset % 4 == 0);
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);
switch (height)
{
case 1:
// Round width up in case it is 1.
for (int x = 0; x < (width + 1) / 2; x += 2)
{
// First 32-bits is two RGB565 colors shared by tile and does not need to be modified.
dest[x] = source[x];
// Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors, the last 3 rows being unused. No flipping should occur.
dest[x + 1] = source[x + 1];
}
break;
case 2:
// Round width up in case it is 1.
for (int x = 0; x < (width + 1) / 2; x += 2)
{
// First 32-bits is two RGB565 colors shared by tile and does not need to be modified.
dest[x] = source[x];
// Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors, the last 2 rows being unused. Only the top 2 rows should be flipped.
dest[x + 1] = ((source[x + 1] << 8) & 0x0000FF00) |
((source[x + 1] >> 8) & 0x000000FF);
}
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 + yoffset) * outputPitch + xoffset * 8);
// Round width up in case it is 1.
for (int x = 0; x < (width + 1) / 2; x += 2)
{
// First 32-bits is two RGB565 colors shared by tile and does not need to be modified.
dest[x] = source[x];
// Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors. All rows should be flipped.
dest[x + 1] = (source[x + 1] >> 24) |
((source[x + 1] << 8) & 0x00FF0000) |
((source[x + 1] >> 8) & 0x0000FF00) |
(source[x + 1] << 24);
}
}
break;
}
}
void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img) void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img)
{ {
IDirect3DTexture9 *newTexture = NULL; IDirect3DTexture9 *newTexture = NULL;
...@@ -819,7 +882,9 @@ void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, G ...@@ -819,7 +882,9 @@ void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, G
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
memcpy(locked.pBits, pixels, imageSize); int inputPitch = ComputeCompressedPitch(width, format);
int inputSize = ComputeCompressedSize(width, height, format);
loadCompressedImageData(0, 0, width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits);
img->surface->UnlockRect(); img->surface->UnlockRect();
} }
...@@ -854,7 +919,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig ...@@ -854,7 +919,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description); loadImageData(xoffset, transformPixelYOffset(yoffset, height, img->height), width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
img->surface->UnlockRect(); img->surface->UnlockRect();
} }
...@@ -898,12 +963,9 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL ...@@ -898,12 +963,9 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
GLsizei inputPitch = ComputeCompressedPitch(width, format); int inputPitch = ComputeCompressedPitch(width, format);
int rows = imageSize / inputPitch; int inputSize = ComputeCompressedSize(width, height, format);
for (int i = 0; i < rows; ++i) loadCompressedImageData(xoffset, transformPixelYOffset(yoffset, height, img->height), width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits);
{
memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
}
img->surface->UnlockRect(); img->surface->UnlockRect();
} }
...@@ -939,7 +1001,7 @@ void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffs ...@@ -939,7 +1001,7 @@ void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffs
} }
D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT sourceLock = {0};
RECT sourceRect = {x, y, x + width, y + height}; RECT sourceRect = transformPixelRect(x, y, width, height, description.Height);
result = surface->LockRect(&sourceLock, &sourceRect, 0); result = surface->LockRect(&sourceLock, &sourceRect, 0);
if (FAILED(result)) if (FAILED(result))
...@@ -964,7 +1026,8 @@ void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffs ...@@ -964,7 +1026,8 @@ void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffs
} }
D3DLOCKED_RECT destLock = {0}; D3DLOCKED_RECT destLock = {0};
RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; int destYOffset = transformPixelYOffset(yoffset, height, image->height);
RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height};
result = image->surface->LockRect(&destLock, &destRect, 0); result = image->surface->LockRect(&destLock, &destRect, 0);
if (FAILED(result)) if (FAILED(result))
...@@ -1325,7 +1388,7 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL ...@@ -1325,7 +1388,7 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
} }
} }
void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{ {
IDirect3DSurface9 *renderTarget = source->getRenderTarget(); IDirect3DSurface9 *renderTarget = source->getRenderTarget();
...@@ -1355,12 +1418,12 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -1355,12 +1418,12 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
if (width != 0 && height != 0 && level < levelCount()) if (width != 0 && height != 0 && level < levelCount())
{ {
RECT sourceRect; RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight());
sourceRect.left = x; sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth());
sourceRect.right = x + width; sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight());
sourceRect.top = y; sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth());
sourceRect.bottom = y + height; sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight());
IDirect3DSurface9 *dest; IDirect3DSurface9 *dest;
HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
...@@ -1374,7 +1437,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -1374,7 +1437,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
mImageArray[level].format = internalFormat; mImageArray[level].format = internalFormat;
} }
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{ {
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height) if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{ {
...@@ -1409,16 +1472,18 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1409,16 +1472,18 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
if (level < levelCount()) if (level < levelCount())
{ {
RECT sourceRect; RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight());
sourceRect.left = x; sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth());
sourceRect.right = x + width; sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight());
sourceRect.top = y; sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth());
sourceRect.bottom = y + height; sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight());
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[level].height);
IDirect3DSurface9 *dest; IDirect3DSurface9 *dest;
HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest); getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, destYOffset, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -1814,12 +1879,11 @@ void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum interna ...@@ -1814,12 +1879,11 @@ void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum interna
void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{ {
int face = faceIndex(faceTarget); int face = faceIndex(faceTarget);
ASSERT(mImageArray[face][level].surface != NULL); ASSERT(mImageArray[face][level].surface != NULL);
if (level < levelCount()) if (level < levelCount())
{ {
IDirect3DSurface9 *destLevel = getCubeMapSurface(face, level); IDirect3DSurface9 *destLevel = getCubeMapSurface(faceTarget, level);
ASSERT(destLevel != NULL); ASSERT(destLevel != NULL);
if (destLevel != NULL) if (destLevel != NULL)
...@@ -1977,7 +2041,7 @@ void TextureCubeMap::updateTexture() ...@@ -1977,7 +2041,7 @@ void TextureCubeMap::updateTexture()
if (img->dirty) if (img->dirty)
{ {
IDirect3DSurface9 *levelSurface = getCubeMapSurface(face, level); IDirect3DSurface9 *levelSurface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
ASSERT(levelSurface != NULL); ASSERT(levelSurface != NULL);
if (levelSurface != NULL) if (levelSurface != NULL)
...@@ -2156,7 +2220,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei ...@@ -2156,7 +2220,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
return !textureOkay; return !textureOkay;
} }
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{ {
IDirect3DSurface9 *renderTarget = source->getRenderTarget(); IDirect3DSurface9 *renderTarget = source->getRenderTarget();
...@@ -2189,11 +2253,11 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat ...@@ -2189,11 +2253,11 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat
if (width > 0 && level < levelCount()) if (width > 0 && level < levelCount())
{ {
RECT sourceRect; RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight());
sourceRect.left = x; sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth());
sourceRect.right = x + width; sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight());
sourceRect.top = y; sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth());
sourceRect.bottom = y + height; sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight());
IDirect3DSurface9 *dest = getCubeMapSurface(target, level); IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
...@@ -2207,24 +2271,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat ...@@ -2207,24 +2271,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat
mImageArray[faceindex][level].format = internalFormat; mImageArray[faceindex][level].format = internalFormat;
} }
IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier, unsigned int level) IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(GLenum face, unsigned int level)
{ {
unsigned int faceIndex;
if (faceIdentifier < 6)
{
faceIndex = faceIdentifier;
}
else if (faceIdentifier >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && faceIdentifier <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
{
faceIndex = faceIdentifier - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
}
else
{
UNREACHABLE();
faceIndex = 0;
}
if (mTexture == NULL) if (mTexture == NULL)
{ {
UNREACHABLE(); UNREACHABLE();
...@@ -2233,12 +2281,12 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier ...@@ -2233,12 +2281,12 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
IDirect3DSurface9 *surface = NULL; IDirect3DSurface9 *surface = NULL;
HRESULT hr = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex), level, &surface); HRESULT hr = mTexture->GetCubeMapSurface(es2dx::ConvertCubeFace(face), level, &surface);
return (SUCCEEDED(hr)) ? surface : NULL; return (SUCCEEDED(hr)) ? surface : NULL;
} }
void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{ {
GLsizei size = mImageArray[faceIndex(target)][level].width; GLsizei size = mImageArray[faceIndex(target)][level].width;
...@@ -2276,15 +2324,17 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2276,15 +2324,17 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
if (level < levelCount()) if (level < levelCount())
{ {
RECT sourceRect; RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight());
sourceRect.left = x; sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth());
sourceRect.right = x + width; sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight());
sourceRect.top = y; sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth());
sourceRect.bottom = y + height; sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight());
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[faceindex][level].width);
IDirect3DSurface9 *dest = getCubeMapSurface(target, level); IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest); getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, destYOffset, dest);
dest->Release(); dest->Release();
} }
} }
...@@ -2347,8 +2397,8 @@ void TextureCubeMap::generateMipmaps() ...@@ -2347,8 +2397,8 @@ void TextureCubeMap::generateMipmaps()
{ {
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1); IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i-1);
IDirect3DSurface9 *lower = getCubeMapSurface(f, i); IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
if (upper != NULL && lower != NULL) if (upper != NULL && lower != NULL)
{ {
...@@ -2414,7 +2464,7 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target) ...@@ -2414,7 +2464,7 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
} }
IDirect3DSurface9 *renderTarget = NULL; IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex(target)), 0, &renderTarget); mTexture->GetCubeMapSurface(es2dx::ConvertCubeFace(target), 0, &renderTarget);
return renderTarget; return renderTarget;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
namespace gl namespace gl
{ {
class Blit; class Blit;
class Framebuffer;
enum enum
{ {
...@@ -70,7 +71,7 @@ class Texture : public RefCountObject ...@@ -70,7 +71,7 @@ class Texture : public RefCountObject
virtual Renderbuffer *getColorbuffer(GLenum target) = 0; virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0; virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) = 0; virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
bool isDirty() const; bool isDirty() const;
...@@ -163,43 +164,45 @@ class Texture : public RefCountObject ...@@ -163,43 +164,45 @@ class Texture : public RefCountObject
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const; GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const;
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer. IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
...@@ -221,8 +224,8 @@ class Texture2D : public Texture ...@@ -221,8 +224,8 @@ class Texture2D : public Texture
void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source); void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source); void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
bool isComplete() const; bool isComplete() const;
bool isCompressed() const; bool isCompressed() const;
...@@ -272,8 +275,8 @@ class TextureCubeMap : public Texture ...@@ -272,8 +275,8 @@ class TextureCubeMap : public Texture
void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source); void copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source); void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
bool isComplete() const; bool isComplete() const;
bool isCompressed() const; bool isCompressed() const;
...@@ -292,9 +295,9 @@ class TextureCubeMap : public Texture ...@@ -292,9 +295,9 @@ class TextureCubeMap : public Texture
virtual bool dirtyImageData() const; virtual bool dirtyImageData() const;
// faceIdentifier is 0-5 or one of the GL_TEXTURE_CUBE_MAP_* enumerants. // face is one of the GL_TEXTURE_CUBE_MAP_* enumerants.
// Returns NULL if the call underlying Direct3D call fails. // Returns NULL if the call underlying Direct3D call fails.
IDirect3DSurface9 *getCubeMapSurface(unsigned int faceIdentifier, unsigned int level); IDirect3DSurface9 *getCubeMapSurface(GLenum face, unsigned int level);
static unsigned int faceIndex(GLenum face); static unsigned int faceIndex(GLenum face);
......
...@@ -1105,7 +1105,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1105,7 +1105,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
texture->copyImage(level, internalformat, x, y, width, height, source); texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
} }
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
{ {
...@@ -1116,7 +1116,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1116,7 +1116,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
texture->copyImage(target, level, internalformat, x, y, width, height, source); texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
} }
else UNREACHABLE(); else UNREACHABLE();
} }
...@@ -1240,7 +1240,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1240,7 +1240,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source); texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBGLESV2_MATHUTIL_H_ #define LIBGLESV2_MATHUTIL_H_
#include <math.h> #include <math.h>
#include <windows.h>
namespace gl namespace gl
{ {
...@@ -38,9 +39,15 @@ inline unsigned int ceilPow2(unsigned int x) ...@@ -38,9 +39,15 @@ inline unsigned int ceilPow2(unsigned int x)
return x; return x;
} }
template<typename T, typename MIN, typename MAX>
inline T clamp(T x, MIN min, MAX max)
{
return x < min ? min : (x > max ? max : x);
}
inline float clamp01(float x) inline float clamp01(float x)
{ {
return x < 0 ? 0 : (x > 1 ? 1 : x); return clamp(x, 0.0f, 1.0f);
} }
template<const int n> template<const int n>
...@@ -61,6 +68,26 @@ inline unsigned int unorm(float x) ...@@ -61,6 +68,26 @@ inline unsigned int unorm(float x)
return (unsigned int)(max * x + 0.5f); return (unsigned int)(max * x + 0.5f);
} }
} }
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;
}
} }
#endif // LIBGLESV2_MATHUTIL_H_ #endif // LIBGLESV2_MATHUTIL_H_
...@@ -189,18 +189,7 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) ...@@ -189,18 +189,7 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format) GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
{ {
switch (format) return ComputeCompressedSize(width, 1, format);
{
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
break;
default:
return 0;
}
ASSERT(width % 4 == 0);
return 8 * width / 4;
} }
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format) GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
...@@ -528,6 +517,39 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) ...@@ -528,6 +517,39 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
return cull; return cull;
} }
D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
{
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)
{
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
face = D3DCUBEMAP_FACE_POSITIVE_X;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
face = D3DCUBEMAP_FACE_NEGATIVE_X;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
face = D3DCUBEMAP_FACE_NEGATIVE_Y;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
face = D3DCUBEMAP_FACE_POSITIVE_Y;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
face = D3DCUBEMAP_FACE_POSITIVE_Z;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
face = D3DCUBEMAP_FACE_NEGATIVE_Z;
break;
default: UNREACHABLE();
}
return face;
}
DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
{ {
return (red ? D3DCOLORWRITEENABLE_RED : 0) | return (red ? D3DCOLORWRITEENABLE_RED : 0) |
......
...@@ -52,6 +52,7 @@ D3DBLENDOP ConvertBlendOp(GLenum blendOp); ...@@ -52,6 +52,7 @@ D3DBLENDOP ConvertBlendOp(GLenum blendOp);
D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter);
......
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