Commit 91fa9ce4 by Geoff Lang

Simplify formatutils9 by exposing the internal structures.

BUG=angle:658 Change-Id: I8134cde4d72796c51613594e15aded86e83c4af7 Reviewed-on: https://chromium-review.googlesource.com/206837Reviewed-by: 's avatarNicolas Capens <capn@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6ba451ba
...@@ -53,8 +53,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour ...@@ -53,8 +53,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
MipGenerationFunction mipFunction = d3d9::GetMipGenerationFunction(sourceDesc.Format); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
ASSERT(mipFunction != NULL); ASSERT(d3dFormatInfo.mipGenerationFunction != NULL);
D3DLOCKED_RECT sourceLocked = {0}; D3DLOCKED_RECT sourceLocked = {0};
result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
...@@ -69,8 +69,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour ...@@ -69,8 +69,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
if (sourceData && destData) if (sourceData && destData)
{ {
mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
destData, destLocked.Pitch, 0); destData, destLocked.Pitch, 0);
} }
destSurface->UnlockRect(); destSurface->UnlockRect();
...@@ -99,22 +99,23 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so ...@@ -99,22 +99,23 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so
{ {
D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT sourceLock = {0};
D3DLOCKED_RECT destLock = {0}; D3DLOCKED_RECT destLock = {0};
source->LockRect(&sourceLock, NULL, 0); source->LockRect(&sourceLock, NULL, 0);
dest->LockRect(&destLock, NULL, 0); dest->LockRect(&destLock, NULL, 0);
if (sourceLock.pBits && destLock.pBits) if (sourceLock.pBits && destLock.pBits)
{ {
D3DSURFACE_DESC desc; D3DSURFACE_DESC desc;
source->GetDesc(&desc); source->GetDesc(&desc);
int blockHeight = d3d9::GetBlockHeight(desc.Format); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
int rows = desc.Height / blockHeight; unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight); unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
bytes <= static_cast<unsigned int>(destLock.Pitch));
for(int i = 0; i < rows; i++) for(unsigned int i = 0; i < rows; i++)
{ {
memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
} }
...@@ -147,12 +148,14 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform ...@@ -147,12 +148,14 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
mInternalFormat = internalformat; mInternalFormat = internalformat;
// compute the d3d format that will be used // compute the d3d format that will be used
mD3DFormat = gl_d3d9::GetTextureFormat(internalformat); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat);
mRenderable = gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN; mD3DFormat = d3d9FormatInfo.texFormat;
mActualFormat = d3dFormatInfo.internalFormat;
mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
SafeRelease(mSurface); SafeRelease(mSurface);
mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat); mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL);
return true; return true;
} }
...@@ -194,10 +197,9 @@ void Image9::createSurface() ...@@ -194,10 +197,9 @@ void Image9::createSurface()
newTexture->GetSurfaceLevel(levelToFetch, &newSurface); newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
SafeRelease(newTexture); SafeRelease(newTexture);
if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
if (d3dFormatInfo.dataInitializerFunction != NULL)
{ {
InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat);
RECT entireRect; RECT entireRect;
entireRect.left = 0; entireRect.left = 0;
entireRect.right = mWidth; entireRect.right = mWidth;
...@@ -208,7 +210,8 @@ void Image9::createSurface() ...@@ -208,7 +210,8 @@ void Image9::createSurface()
result = newSurface->LockRect(&lockedRect, &entireRect, 0); result = newSurface->LockRect(&lockedRect, &entireRect, 0);
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
initializeFunc(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits), lockedRect.Pitch, 0); d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits),
lockedRect.Pitch, 0);
result = newSurface->UnlockRect(); result = newSurface->UnlockRect();
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
...@@ -260,7 +263,7 @@ bool Image9::isDirty() const ...@@ -260,7 +263,7 @@ bool Image9::isDirty() const
{ {
// Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet
// if initialization is required before use. // if initialization is required before use.
return (mSurface || gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) && mDirty; return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
} }
IDirect3DSurface9 *Image9::getSurface() IDirect3DSurface9 *Image9::getSurface()
...@@ -390,8 +393,8 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width ...@@ -390,8 +393,8 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(loadFunction != NULL); ASSERT(d3dFormatInfo.loadFunction != NULL);
RECT lockRect = RECT lockRect =
{ {
...@@ -406,9 +409,9 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width ...@@ -406,9 +409,9 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
return; return;
} }
loadFunction(width, height, depth, d3dFormatInfo.loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock(); unlock();
} }
...@@ -423,11 +426,12 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs ...@@ -423,11 +426,12 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0);
ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); ASSERT(d3d9FormatInfo.loadFunction != NULL);
ASSERT(loadFunction != NULL);
RECT lockRect = RECT lockRect =
{ {
...@@ -442,9 +446,9 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs ...@@ -442,9 +446,9 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
return; return;
} }
loadFunction(width, height, depth, d3d9FormatInfo.loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch, reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock(); unlock();
} }
......
...@@ -33,8 +33,9 @@ RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) ...@@ -33,8 +33,9 @@ RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
mHeight = description.Height; mHeight = description.Height;
mDepth = 1; mDepth = 1;
mInternalFormat = d3d9_gl::GetInternalFormat(description.Format); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
mActualFormat = d3d9_gl::GetInternalFormat(description.Format); mInternalFormat = d3dFormatInfo.internalFormat;
mActualFormat = d3dFormatInfo.internalFormat;
mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType); mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
} }
} }
...@@ -44,7 +45,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -44,7 +45,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
mRenderer = Renderer9::makeRenderer9(renderer); mRenderer = Renderer9::makeRenderer9(renderer);
mRenderTarget = NULL; mRenderTarget = NULL;
D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat);
const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
GLuint supportedSamples = textureCaps.getNearestSamples(samples); GLuint supportedSamples = textureCaps.getNearestSamples(samples);
...@@ -60,15 +62,14 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -60,15 +62,14 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{ {
result = device->CreateDepthStencilSurface(width, height, renderFormat, result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples), gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL); 0, FALSE, &mRenderTarget, NULL);
} }
else else
{ {
requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat); requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
result = device->CreateRenderTarget(width, height, renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples), gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL); 0, FALSE, &mRenderTarget, NULL);
} }
...@@ -100,7 +101,7 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -100,7 +101,7 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
mDepth = 1; mDepth = 1;
mInternalFormat = internalFormat; mInternalFormat = internalFormat;
mSamples = supportedSamples; mSamples = supportedSamples;
mActualFormat = d3d9_gl::GetInternalFormat(renderFormat); mActualFormat = d3dFormatInfo.internalFormat;
} }
RenderTarget9::~RenderTarget9() RenderTarget9::~RenderTarget9()
......
...@@ -352,8 +352,6 @@ EGLint Renderer9::initialize() ...@@ -352,8 +352,6 @@ EGLint Renderer9::initialize()
initializeDevice(); initializeDevice();
d3d9::InitializeVertexTranslations(this);
return EGL_SUCCESS; return EGL_SUCCESS;
} }
...@@ -419,40 +417,24 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList) ...@@ -419,40 +417,24 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList)
for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
{ {
D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]);
const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); if (renderTargetFormatCaps.renderable)
if (SUCCEEDED(result))
{ {
for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
{ {
D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]);
HRESULT result = D3D_OK; const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN)
if(depthStencilFormat != D3DFMT_UNKNOWN)
{
result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
}
if (SUCCEEDED(result))
{ {
if(depthStencilFormat != D3DFMT_UNKNOWN) ConfigDesc newConfig;
{ newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
} newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]);
if (SUCCEEDED(result)) newConfig.es3Capable = false;
{
ConfigDesc newConfig; (*configDescList)[numConfigs++] = newConfig;
newConfig.renderTargetFormat = d3d9_gl::GetInternalFormat(renderTargetFormat);
newConfig.depthStencilFormat = d3d9_gl::GetInternalFormat(depthStencilFormat);
newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat);
newConfig.es3Capable = false;
(*configDescList)[numConfigs++] = newConfig;
}
} }
} }
} }
...@@ -2763,7 +2745,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2763,7 +2745,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
inputPitch = lock.Pitch; inputPitch = lock.Pitch;
} }
const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3d9_gl::GetInternalFormat(desc.Format)); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat);
if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) if (sourceFormatInfo.format == format && sourceFormatInfo.type == type)
{ {
// Direct copy possible // Direct copy possible
...@@ -2775,9 +2758,12 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2775,9 +2758,12 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
} }
else else
{ {
const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type);
const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type); const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type);
const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type);
if (fastCopyFunc) if (fastCopyFunc)
{ {
// Fast copy is possible through some special function // Fast copy is possible through some special function
...@@ -2794,8 +2780,6 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2794,8 +2780,6 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
} }
else else
{ {
ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format);
gl::ColorF temp; gl::ColorF temp;
for (int y = 0; y < rect.bottom - rect.top; y++) for (int y = 0; y < rect.bottom - rect.top; y++)
{ {
...@@ -2806,7 +2790,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2806,7 +2790,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
// readFunc and writeFunc will be using the same type of color, CopyTexImage // readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise. // will not allow the copy otherwise.
readFunc(src, &temp); sourceD3DFormatInfo.colorReadFunction(src, &temp);
destFormatTypeInfo.colorWriteFunction(&temp, dest); destFormatTypeInfo.colorWriteFunction(&temp, dest);
} }
} }
...@@ -3100,13 +3084,12 @@ bool Renderer9::getLUID(LUID *adapterLuid) const ...@@ -3100,13 +3084,12 @@ bool Renderer9::getLUID(LUID *adapterLuid) const
rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{ {
return d3d9::GetVertexConversionType(vertexFormat); return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType;
} }
GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
{ {
D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat); return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType;
return d3d9::GetDeclTypeComponentType(declType);
} }
void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
......
...@@ -101,9 +101,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -101,9 +101,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
pShareHandle = &mShareHandle; pShareHandle = &mShareHandle;
} }
const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat);
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
gl_d3d9::GetTextureFormat(mBackBufferFormat), backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); pShareHandle);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Could not create offscreen texture: %08lX", result); ERR("Could not create offscreen texture: %08lX", result);
...@@ -150,12 +151,14 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -150,12 +151,14 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(oldRenderTarget); SafeRelease(oldRenderTarget);
} }
const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat);
if (mWindow) if (mWindow)
{ {
D3DPRESENT_PARAMETERS presentParameters = {0}; D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat); presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
presentParameters.BackBufferCount = 1; presentParameters.BackBufferCount = 1;
presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat); presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0; presentParameters.Flags = 0;
presentParameters.hDeviceWindow = mWindow; presentParameters.hDeviceWindow = mWindow;
...@@ -207,7 +210,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -207,7 +210,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
if (mDepthBufferFormat != GL_NONE) if (mDepthBufferFormat != GL_NONE)
{ {
result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
gl_d3d9::GetRenderFormat(mDepthBufferFormat), depthBufferd3dFormatInfo.renderFormat,
D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);
if (FAILED(result)) if (FAILED(result))
......
...@@ -44,11 +44,12 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) ...@@ -44,11 +44,12 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget)
DWORD d3dusage = 0; DWORD d3dusage = 0;
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{ {
d3dusage |= D3DUSAGE_DEPTHSTENCIL; d3dusage |= D3DUSAGE_DEPTHSTENCIL;
} }
else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN)) else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN))
{ {
d3dusage |= D3DUSAGE_RENDERTARGET; d3dusage |= D3DUSAGE_RENDERTARGET;
} }
...@@ -107,11 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat ...@@ -107,11 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
IDirect3DDevice9 *device = mRenderer->getDevice(); IDirect3DDevice9 *device = mRenderer->getDevice();
D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel); d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -208,11 +209,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo ...@@ -208,11 +209,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo
{ {
IDirect3DDevice9 *device = mRenderer->getDevice(); IDirect3DDevice9 *device = mRenderer->getDevice();
int height = size; int height = size;
D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel); d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
if (FAILED(result)) if (FAILED(result))
{ {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
namespace rx namespace rx
{ {
VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer)
{ {
mVertexBuffer = NULL; mVertexBuffer = NULL;
mBufferSize = 0; mBufferSize = 0;
...@@ -117,7 +117,8 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con ...@@ -117,7 +117,8 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con
} }
gl::VertexFormat vertexFormat(attrib, currentValue.Type); gl::VertexFormat vertexFormat(attrib, currentValue.Type);
bool needsConversion = (d3d9::GetVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) > 0; const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0;
if (!needsConversion && inputStride == elementSize) if (!needsConversion && inputStride == elementSize)
{ {
...@@ -126,8 +127,7 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con ...@@ -126,8 +127,7 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con
} }
else else
{ {
VertexCopyFunction copyFunction = d3d9::GetVertexCopyFunction(vertexFormat); d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
copyFunction(input, inputStride, count, mapPtr);
} }
mVertexBuffer->Unlock(); mVertexBuffer->Unlock();
...@@ -200,10 +200,10 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const ...@@ -200,10 +200,10 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
} }
bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired) unsigned int *outSpaceRequired) const
{ {
gl::VertexFormat vertexFormat(attrib, GL_FLOAT); gl::VertexFormat vertexFormat(attrib, GL_FLOAT);
unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat); const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
if (attrib.enabled) if (attrib.enabled)
{ {
...@@ -218,11 +218,11 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t ...@@ -218,11 +218,11 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t
elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
} }
if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
{ {
if (outSpaceRequired) if (outSpaceRequired)
{ {
*outSpaceRequired = elementSize * elementCount; *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount;
} }
return true; return true;
} }
......
...@@ -18,7 +18,7 @@ class Renderer9; ...@@ -18,7 +18,7 @@ class Renderer9;
class VertexBuffer9 : public VertexBuffer class VertexBuffer9 : public VertexBuffer
{ {
public: public:
explicit VertexBuffer9(rx::Renderer9 *const renderer); explicit VertexBuffer9(rx::Renderer9 *renderer);
virtual ~VertexBuffer9(); virtual ~VertexBuffer9();
virtual bool initialize(unsigned int size, bool dynamicUsage); virtual bool initialize(unsigned int size, bool dynamicUsage);
...@@ -39,14 +39,14 @@ class VertexBuffer9 : public VertexBuffer ...@@ -39,14 +39,14 @@ class VertexBuffer9 : public VertexBuffer
private: private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
rx::Renderer9 *const mRenderer; rx::Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mVertexBuffer; IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mBufferSize; unsigned int mBufferSize;
bool mDynamicUsage; bool mDynamicUsage;
static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired); unsigned int *outSpaceRequired) const;
}; };
} }
......
...@@ -74,6 +74,9 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl ...@@ -74,6 +74,9 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
} }
} }
D3DCAPS9 caps;
device->GetDeviceCaps(&caps);
D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0]; D3DVERTEXELEMENT9 *element = &elements[0];
...@@ -133,10 +136,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl ...@@ -133,10 +136,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
} }
gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT);
const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat);
element->Stream = stream; element->Stream = stream;
element->Offset = 0; element->Offset = 0;
element->Type = d3d9::GetNativeVertexFormat(vertexFormat); element->Type = d3d9VertexInfo.nativeFormat;
element->Method = D3DDECLMETHOD_DEFAULT; element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD; element->Usage = D3DDECLUSAGE_TEXCOORD;
element->UsageIndex = programBinary->getSemanticIndex(i); element->UsageIndex = programBinary->getSemanticIndex(i);
......
...@@ -18,255 +18,134 @@ ...@@ -18,255 +18,134 @@
namespace rx namespace rx
{ {
// Each GL internal format corresponds to one D3D format and data loading function. namespace d3d9
// Due to not all formats being available all the time, some of the function/format types are wrapped
// in templates that perform format support queries on a Renderer9 object which is supplied
// when requesting the function or format.
typedef bool(*FallbackPredicateFunction)();
template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
static void FallbackLoad(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{
if (pred())
{
prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
}
else
{
fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
}
}
static void UnreachableLoad(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{ {
UNREACHABLE();
}
const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
struct D3D9FormatInfo struct D3D9FastCopyFormat
{ {
D3DFORMAT mTexFormat; GLenum destFormat;
D3DFORMAT mRenderFormat; GLenum destType;
LoadImageFunction mLoadFunction; ColorCopyFunction copyFunction;
D3D9FormatInfo() D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction)
: mTexFormat(D3DFMT_NULL), mRenderFormat(D3DFMT_NULL), mLoadFunction(NULL) : destFormat(destFormat), destType(destType), copyFunction(copyFunction)
{ } { }
D3D9FormatInfo(D3DFORMAT textureFormat, D3DFORMAT renderFormat, LoadImageFunction loadFunc) bool operator<(const D3D9FastCopyFormat& other) const
: mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc) {
{ } return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0;
}
}; };
typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair; typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap;
typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap;
static D3D9FormatMap BuildD3D9FormatMap() static D3D9FastCopyMap BuildFastCopyMap()
{ {
D3D9FormatMap map; D3D9FastCopyMap map;
// | Internal format | Texture format | Render format | Load function | map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRAUByteToRGBAUByte)));
map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D32, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ))); // TODO: What's the texture format?
map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> )));
map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>)));
map.insert(D3D9FormatPair(GL_RG32F_EXT, D3D9FormatInfo(D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> )));
map.insert(D3D9FormatPair(GL_R32F_EXT, D3D9FormatInfo(D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> )));
map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F )));
map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F )));
map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F )));
map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> )));
map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> )));
map.insert(D3D9FormatPair(GL_RG16F_EXT, D3D9FormatInfo(D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> )));
map.insert(D3D9FormatPair(GL_R16F_EXT, D3D9FormatInfo(D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> )));
map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F )));
map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F )));
map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F )));
map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>)));
map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 )));
map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 )));
map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>)));
map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 )));
map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 )));
map.insert(D3D9FormatPair(GL_R8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 )));
map.insert(D3D9FormatPair(GL_RG8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 )));
map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> )));
map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 )));
map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 )));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> )));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> )));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> )));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> )));
// These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
// then changing the format and loading function appropriately.
map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> )));
map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> )));
return map; return map;
} }
static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo) // A map to determine the pixel size and mip generation function of a given D3D format
typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap;
D3DFormat::D3DFormat()
: pixelBytes(0),
blockWidth(0),
blockHeight(0),
internalFormat(GL_NONE),
mipGenerationFunction(NULL),
colorReadFunction(NULL),
fastCopyFunctions()
{ {
static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
} }
// A map to determine the pixel size and mip generation function of a given D3D format ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const
struct D3DFormatInfo
{ {
GLuint mPixelBits; FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
GLuint mBlockWidth; return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
GLuint mBlockHeight; }
GLenum mInternalFormat;
MipGenerationFunction mMipGenerationFunction;
ColorReadFunction mColorReadFunction;
D3DFormatInfo() static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth,
: mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL), GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc,
mColorReadFunction(NULL) ColorReadFunction colorReadFunc)
{ } {
D3DFormat info;
info.pixelBytes = bits / 8;
info.blockWidth = blockWidth;
info.blockHeight = blockHeight;
info.internalFormat = internalFormat;
info.mipGenerationFunction = mipFunc;
info.colorReadFunction = colorReadFunc;
D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum internalFormat, static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
MipGenerationFunction mipFunc, ColorReadFunction readFunc) std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format);
: mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat), for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) {
{ } info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
}; }
typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair; map->insert(std::make_pair(format, info));
typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap; }
static D3D9FormatInfoMap BuildD3D9FormatInfoMap() static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
{ {
D3D9FormatInfoMap map; D3D9FormatInfoMap map;
// | D3DFORMAT | | S |W |H | Internal format | Mip generation function | Color read function | // | D3DFORMAT | S |W |H | Internal format | Mip generation function | Color read function |
map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, GL_NONE, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_R16F, D3DFormatInfo( 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_G16R16F, D3DFormatInfo( 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>))); InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
map.insert(D3D9FormatInfoPair(D3DFMT_R32F, D3DFormatInfo( 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F, D3DFormatInfo( 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ))); InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> );
map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>))); InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL );
map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ))); InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL );
return map; return map;
} }
static const D3D9FormatInfoMap &GetD3D9FormatInfoMap() const D3DFormat &GetD3DFormatInfo(D3DFORMAT format)
{ {
static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
return infoMap;
}
static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
{
const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end()) if (iter != infoMap.end())
{ {
if (outFormatInfo) return iter->second;
{
*outFormatInfo = iter->second;
}
return true;
} }
else else
{ {
return false; static const D3DFormat defaultInfo;
return defaultInfo;
} }
} }
static d3d9::D3DFormatSet BuildAllD3DFormatSet()
{
d3d9::D3DFormatSet set;
const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
{
set.insert(i->first);
}
return set;
}
struct D3D9FastCopyFormat
{
D3DFORMAT mSourceFormat;
GLenum mDestFormat;
GLenum mDestType;
D3D9FastCopyFormat(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType)
: mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType)
{ }
bool operator<(const D3D9FastCopyFormat& other) const
{
return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0;
}
};
typedef std::map<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyMap;
typedef std::pair<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyPair;
static D3D9FastCopyMap BuildFastCopyMap()
{
D3D9FastCopyMap map;
map.insert(D3D9FastCopyPair(D3D9FastCopyFormat(D3DFMT_A8R8G8B8, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte));
return map;
}
typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair; typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap; typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
...@@ -275,160 +154,139 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() ...@@ -275,160 +154,139 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
{ {
InternalFormatInitialzerMap map; InternalFormatInitialzerMap map;
map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>));
map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
return map; return map;
} }
static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap() // Each GL internal format corresponds to one D3D format and data loading function.
{ // Due to not all formats being available all the time, some of the function/format types are wrapped
static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap(); // in templates that perform format support queries on a Renderer9 object which is supplied
return map; // when requesting the function or format.
}
namespace d3d9 typedef bool(*FallbackPredicateFunction)();
{
MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format) template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
static void FallbackLoad(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{ {
D3DFormatInfo d3dFormatInfo; if (pred())
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{ {
return d3dFormatInfo.mMipGenerationFunction; prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
} }
else else
{ {
UNREACHABLE(); fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
return NULL;
} }
} }
LoadImageFunction GetImageLoadFunction(GLenum internalFormat) static void UnreachableLoad(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{ {
D3D9FormatInfo d3d9FormatInfo; UNREACHABLE();
if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mLoadFunction;
}
else
{
UNREACHABLE();
return NULL;
}
} }
GLuint GetFormatPixelBytes(D3DFORMAT format) typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
{ typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mPixelBits / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockWidth(D3DFORMAT format) TextureFormat::TextureFormat()
: texFormat(D3DFMT_NULL),
renderFormat(D3DFMT_NULL),
dataInitializerFunction(NULL),
loadFunction(UnreachableLoad)
{ {
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mBlockWidth;
}
else
{
UNREACHABLE();
return 0;
}
} }
GLuint GetBlockHeight(D3DFORMAT format) static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalFormat, D3DFORMAT texFormat,
D3DFORMAT renderFormat, LoadImageFunction loadFunction)
{ {
D3DFormatInfo d3dFormatInfo; TextureFormat info;
if (GetD3D9FormatInfo(format, &d3dFormatInfo)) info.texFormat = texFormat;
{ info.renderFormat = renderFormat;
return d3dFormatInfo.mBlockHeight;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height) static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap();
{ InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat);
D3DFormatInfo d3dFormatInfo; info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth;
GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight;
return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; info.loadFunction = loadFunction;
}
else map->insert(std::make_pair(internalFormat, info));
{
UNREACHABLE();
return 0;
}
} }
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) static D3D9FormatMap BuildD3D9FormatMap()
{ {
D3DFormatInfo d3dFormatInfo; D3D9FormatMap map;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
int upsampleCount = 0;
GLsizei blockWidth = d3dFormatInfo.mBlockWidth; // | Internal format | Texture format | Render format | Load function |
GLsizei blockHeight = d3dFormatInfo.mBlockHeight; InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad );
InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad );
InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, D3DFMT_INTZ, D3DFMT_D32, UnreachableLoad );
InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad );
InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8, D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ); // TODO: What's the texture format?
InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> );
InsertD3D9FormatInfo(&map, GL_RGB32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>);
InsertD3D9FormatInfo(&map, GL_RG32F_EXT, D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> );
InsertD3D9FormatInfo(&map, GL_R32F_EXT, D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> );
InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F );
InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F );
InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F );
InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> );
InsertD3D9FormatInfo(&map, GL_RGB16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> );
InsertD3D9FormatInfo(&map, GL_RG16F_EXT, D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> );
InsertD3D9FormatInfo(&map, GL_R16F_EXT, D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> );
InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F );
InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F );
InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F );
InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>);
InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 );
InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>);
InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 );
InsertD3D9FormatInfo(&map, GL_RG8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 );
InsertD3D9FormatInfo(&map, GL_BGRA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> );
InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> );
InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> );
InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> );
InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> );
// Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) // then changing the format and loading function appropriately.
{ InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> );
while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> );
{
*requestWidth <<= 1;
*requestHeight <<= 1;
upsampleCount++;
}
}
*levelOffset = upsampleCount;
}
}
const D3DFormatSet &GetAllUsedD3DFormats() return map;
{
static const D3DFormatSet formatSet = BuildAllD3DFormatSet();
return formatSet;
} }
ColorReadFunction GetColorReadFunction(D3DFORMAT format) const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
{ {
D3DFormatInfo d3dFormatInfo; static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
if (GetD3D9FormatInfo(format, &d3dFormatInfo)) D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{ {
return d3dFormatInfo.mColorReadFunction; return iter->second;
} }
else else
{ {
UNREACHABLE(); static const TextureFormat defaultInfo;
return NULL; return defaultInfo;
} }
} }
ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
{
static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
D3D9FastCopyMap::const_iterator iter = fastCopyMap.find(D3D9FastCopyFormat(sourceFormat, destFormat, destType));
return (iter != fastCopyMap.end()) ? iter->second : NULL;
}
GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
{ {
switch (declType) switch (declType)
{ {
...@@ -451,27 +309,13 @@ GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) ...@@ -451,27 +309,13 @@ GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
// Attribute format conversion // Attribute format conversion
enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
struct FormatConverter
{
bool identity;
std::size_t outputElementSize;
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
D3DDECLTYPE d3dDeclType;
};
struct TranslationDescription struct TranslationDescription
{ {
DWORD capsFlag; DWORD capsFlag;
FormatConverter preferredConversion; VertexFormat preferredConversion;
FormatConverter fallbackConversion; VertexFormat fallbackConversion;
}; };
static unsigned int typeIndex(GLenum type);
static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute);
bool mTranslationsInitialized = false;
FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
// Mapping from OpenGL-ES vertex attrib type to D3D decl type: // Mapping from OpenGL-ES vertex attrib type to D3D decl type:
// //
// BYTE SHORT (Cast) // BYTE SHORT (Cast)
...@@ -623,14 +467,35 @@ public: ...@@ -623,14 +467,35 @@ public:
enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
}; };
VertexFormat::VertexFormat()
: conversionType(VERTEX_CONVERT_NONE),
outputElementSize(0),
copyFunction(NULL),
nativeFormat(D3DDECLTYPE_UNUSED),
componentType(GL_NONE)
{
}
// Initialize a TranslationInfo // Initialize a TranslationInfo
VertexFormat CreateVertexFormatInfo(bool identity, size_t elementSize, VertexCopyFunction copyFunc, D3DDECLTYPE nativeFormat)
{
VertexFormat formatInfo;
formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU;
formatInfo.outputElementSize = elementSize;
formatInfo.copyFunction = copyFunc;
formatInfo.nativeFormat = nativeFormat;
formatInfo.componentType = GetDeclTypeComponentType(nativeFormat);
return formatInfo;
}
#define TRANSLATION(type, norm, size, preferred) \ #define TRANSLATION(type, norm, size, preferred) \
{ \ CreateVertexFormatInfo \
( \
Converter<type, norm, size, preferred>::identity, \ Converter<type, norm, size, preferred>::identity, \
Converter<type, norm, size, preferred>::finalSize, \ Converter<type, norm, size, preferred>::finalSize, \
Converter<type, norm, size, preferred>::convertArray, \ Converter<type, norm, size, preferred>::convertArray, \
static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \ static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
} )
#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ #define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
{ \ { \
...@@ -651,168 +516,63 @@ public: ...@@ -651,168 +516,63 @@ public:
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
} }
const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] static inline unsigned int ComputeTypeIndex(GLenum type)
{ {
TRANSLATIONS_FOR_TYPE(GL_BYTE), switch (type)
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), {
TRANSLATIONS_FOR_TYPE(GL_SHORT), case GL_BYTE: return 0;
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), case GL_UNSIGNED_BYTE: return 1;
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), case GL_SHORT: return 2;
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) case GL_UNSIGNED_SHORT: return 3;
}; case GL_FIXED: return 4;
case GL_FLOAT: return 5;
void InitializeVertexTranslations(const rx::Renderer9 *renderer) default: UNREACHABLE(); return 5;
{ }
DWORD declTypes = renderer->getCapsDeclTypes(); }
for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat)
{
static bool initialized = false;
static DWORD intializedDeclTypes = 0;
static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
if (!initialized)
{ {
for (unsigned int j = 0; j < 2; j++) const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
{ {
for (unsigned int k = 0; k < 4; k++) TRANSLATIONS_FOR_TYPE(GL_BYTE),
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
TRANSLATIONS_FOR_TYPE(GL_SHORT),
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
};
for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
{
for (unsigned int j = 0; j < 2; j++)
{ {
if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) for (unsigned int k = 0; k < 4; k++)
{
mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
}
else
{ {
mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; if (translations[i][j][k].capsFlag == 0 || (supportedDeclTypes & translations[i][j][k].capsFlag) != 0)
{
formatConverters[i][j][k] = translations[i][j][k].preferredConversion;
}
else
{
formatConverters[i][j][k] = translations[i][j][k].fallbackConversion;
}
} }
} }
} }
initialized = true;
intializedDeclTypes = supportedDeclTypes;
} }
}
unsigned int typeIndex(GLenum type)
{
switch (type)
{
case GL_BYTE: return 0;
case GL_UNSIGNED_BYTE: return 1;
case GL_SHORT: return 2;
case GL_UNSIGNED_SHORT: return 3;
case GL_FIXED: return 4;
case GL_FLOAT: return 5;
default: UNREACHABLE(); return 5; ASSERT(intializedDeclTypes == supportedDeclTypes);
}
}
const FormatConverter &formatConverter(const gl::VertexFormat &vertexFormat)
{
// Pure integer attributes only supported in ES3.0 // Pure integer attributes only supported in ES3.0
ASSERT(!vertexFormat.mPureInteger); ASSERT(!vertexFormat.mPureInteger);
return mFormatConverters[typeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1];
}
VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat)
{
return formatConverter(vertexFormat).convertArray;
}
size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat)
{
return formatConverter(vertexFormat).outputElementSize;
}
VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat)
{
return (formatConverter(vertexFormat).identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU);
}
D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat)
{
return formatConverter(vertexFormat).d3dDeclType;
}
}
namespace gl_d3d9
{
D3DFORMAT GetTextureFormat(GLenum internalFormat)
{
D3D9FormatInfo d3d9FormatInfo;
if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mTexFormat;
}
else
{
return D3DFMT_UNKNOWN;
}
}
D3DFORMAT GetRenderFormat(GLenum internalFormat)
{
D3D9FormatInfo d3d9FormatInfo;
if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mRenderFormat;
}
else
{
return D3DFMT_UNKNOWN;
}
}
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples)
{
return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
}
bool RequiresTextureDataInitialization(GLint internalFormat)
{
const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap();
return map.find(internalFormat) != map.end();
}
InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat)
{
const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap();
InternalFormatInitialzerMap::const_iterator iter = map.find(internalFormat);
if (iter != map.end())
{
return iter->second;
}
else
{
UNREACHABLE();
return NULL;
}
}
}
namespace d3d9_gl
{
GLenum GetInternalFormat(D3DFORMAT format)
{
static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end())
{
return iter->second.mInternalFormat;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
{
return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
}
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
{
GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat);
GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format;
return convertedFormat == format;
} }
} }
......
...@@ -20,55 +20,50 @@ class Renderer9; ...@@ -20,55 +20,50 @@ class Renderer9;
namespace d3d9 namespace d3d9
{ {
typedef std::set<D3DFORMAT> D3DFormatSet; typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format); struct D3DFormat
LoadImageFunction GetImageLoadFunction(GLenum internalFormat); {
D3DFormat();
GLuint GetFormatPixelBytes(D3DFORMAT format);
GLuint GetBlockWidth(D3DFORMAT format);
GLuint GetBlockHeight(D3DFORMAT format);
GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height);
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
const D3DFormatSet &GetAllUsedD3DFormats();
ColorReadFunction GetColorReadFunction(D3DFORMAT format);
ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType);
VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat); GLuint pixelBytes;
size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat); GLuint blockWidth;
VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat); GLuint blockHeight;
D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat);
GLenum GetDeclTypeComponentType(D3DDECLTYPE declType); GLenum internalFormat;
int GetDeclTypeComponentCount(D3DDECLTYPE declType);
bool IsDeclTypeNormalized(D3DDECLTYPE declType);
void InitializeVertexTranslations(const rx::Renderer9 *renderer); MipGenerationFunction mipGenerationFunction;
ColorReadFunction colorReadFunction;
} FastCopyFunctionMap fastCopyFunctions;
ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
};
const D3DFormat &GetD3DFormatInfo(D3DFORMAT format);
namespace gl_d3d9 struct VertexFormat
{ {
VertexFormat();
D3DFORMAT GetTextureFormat(GLenum internalForma); VertexConversionType conversionType;
D3DFORMAT GetRenderFormat(GLenum internalFormat); size_t outputElementSize;
VertexCopyFunction copyFunction;
D3DDECLTYPE nativeFormat;
GLenum componentType;
};
const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat);
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); struct TextureFormat
{
TextureFormat();
bool RequiresTextureDataInitialization(GLint internalFormat); D3DFORMAT texFormat;
InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); D3DFORMAT renderFormat;
} InitializeTextureDataFunction dataInitializerFunction;
namespace d3d9_gl
{
GLenum GetInternalFormat(D3DFORMAT format); LoadImageFunction loadFunction;
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); };
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
} }
......
...@@ -246,33 +246,49 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT ...@@ -246,33 +246,49 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT
} }
} }
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples)
{
return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
}
} }
namespace d3d9_gl namespace d3d9_gl
{ {
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
{
return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
}
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
{
GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat;
GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format;
return convertedFormat == format;
}
static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType, static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType,
UINT adapter, D3DFORMAT adapterFormat) UINT adapter, D3DFORMAT adapterFormat)
{ {
gl::TextureCaps textureCaps; gl::TextureCaps textureCaps;
D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
gl::InternalFormat formatInfo = gl::GetInternalFormatInfo(internalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{ {
textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, renderFormat)); textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, renderFormat)); textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, renderFormat)) || textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)) ||
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, renderFormat)); SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
} }
else else
{ {
D3DFORMAT textureFormat = gl_d3d9::GetTextureFormat(internalFormat); textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) &&
textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, textureFormat)) && SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat));
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, textureFormat)); textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, textureFormat)); textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) ||
textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, textureFormat)) || SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, textureFormat));
} }
textureCaps.sampleCounts.insert(1); textureCaps.sampleCounts.insert(1);
...@@ -280,7 +296,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 ...@@ -280,7 +296,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3
{ {
D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i);
HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, renderFormat, TRUE, multisampleType, NULL); HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
textureCaps.sampleCounts.insert(i); textureCaps.sampleCounts.insert(i);
...@@ -411,4 +427,36 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT ...@@ -411,4 +427,36 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
} }
namespace d3d9
{
GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height)
{
const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth;
GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight;
return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight);
}
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
{
const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
int upsampleCount = 0;
// Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
if (isImage || *requestWidth < static_cast<GLsizei>(d3dFormatInfo.blockWidth) ||
*requestHeight < static_cast<GLsizei>(d3dFormatInfo.blockHeight))
{
while (*requestWidth % d3dFormatInfo.blockWidth != 0 || *requestHeight % d3dFormatInfo.blockHeight != 0)
{
*requestWidth <<= 1;
*requestHeight <<= 1;
upsampleCount++;
}
}
*levelOffset = upsampleCount;
}
}
} }
...@@ -31,11 +31,17 @@ DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); ...@@ -31,11 +31,17 @@ DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
} }
namespace d3d9_gl namespace d3d9_gl
{ {
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps,
gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions); gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
...@@ -44,6 +50,10 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT ...@@ -44,6 +50,10 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
namespace d3d9 namespace d3d9
{ {
GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height);
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
inline bool isDeviceLostError(HRESULT errorCode) inline bool isDeviceLostError(HRESULT errorCode)
{ {
switch (errorCode) switch (errorCode)
......
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