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
......
...@@ -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";
......
...@@ -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