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
ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
MipGenerationFunction mipFunction = d3d9::GetMipGenerationFunction(sourceDesc.Format);
ASSERT(mipFunction != NULL);
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
ASSERT(d3dFormatInfo.mipGenerationFunction != NULL);
D3DLOCKED_RECT sourceLocked = {0};
result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
......@@ -69,8 +69,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
if (sourceData && destData)
{
mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
destData, destLocked.Pitch, 0);
d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
destData, destLocked.Pitch, 0);
}
destSurface->UnlockRect();
......@@ -99,22 +99,23 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so
{
D3DLOCKED_RECT sourceLock = {0};
D3DLOCKED_RECT destLock = {0};
source->LockRect(&sourceLock, NULL, 0);
dest->LockRect(&destLock, NULL, 0);
if (sourceLock.pBits && destLock.pBits)
{
D3DSURFACE_DESC desc;
source->GetDesc(&desc);
int blockHeight = d3d9::GetBlockHeight(desc.Format);
int rows = desc.Height / blockHeight;
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight);
ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch);
unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
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);
}
......@@ -147,12 +148,14 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
mInternalFormat = internalformat;
// compute the d3d format that will be used
mD3DFormat = gl_d3d9::GetTextureFormat(internalformat);
mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat);
mRenderable = gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN;
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat);
mD3DFormat = d3d9FormatInfo.texFormat;
mActualFormat = d3dFormatInfo.internalFormat;
mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
SafeRelease(mSurface);
mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat);
mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL);
return true;
}
......@@ -194,10 +197,9 @@ void Image9::createSurface()
newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
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;
entireRect.left = 0;
entireRect.right = mWidth;
......@@ -208,7 +210,8 @@ void Image9::createSurface()
result = newSurface->LockRect(&lockedRect, &entireRect, 0);
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();
ASSERT(SUCCEEDED(result));
......@@ -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
// if initialization is required before use.
return (mSurface || gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) && mDirty;
return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
}
IDirect3DSurface9 *Image9::getSurface()
......@@ -390,8 +393,8 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat);
ASSERT(loadFunction != NULL);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(d3dFormatInfo.loadFunction != NULL);
RECT lockRect =
{
......@@ -406,9 +409,9 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
return;
}
loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
d3dFormatInfo.loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
}
......@@ -423,11 +426,12 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0);
ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0);
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat);
ASSERT(loadFunction != NULL);
ASSERT(d3d9FormatInfo.loadFunction != NULL);
RECT lockRect =
{
......@@ -442,9 +446,9 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
return;
}
loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
d3d9FormatInfo.loadFunction(width, height, depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
}
......
......@@ -33,8 +33,9 @@ RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
mHeight = description.Height;
mDepth = 1;
mInternalFormat = d3d9_gl::GetInternalFormat(description.Format);
mActualFormat = d3d9_gl::GetInternalFormat(description.Format);
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
mInternalFormat = d3dFormatInfo.internalFormat;
mActualFormat = d3dFormatInfo.internalFormat;
mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
}
}
......@@ -44,7 +45,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
mRenderer = Renderer9::makeRenderer9(renderer);
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);
GLuint supportedSamples = textureCaps.getNearestSamples(samples);
......@@ -60,15 +62,14 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
result = device->CreateDepthStencilSurface(width, height, renderFormat,
result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL);
}
else
{
requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat);
result = device->CreateRenderTarget(width, height, renderFormat,
requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL);
}
......@@ -100,7 +101,7 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
mDepth = 1;
mInternalFormat = internalFormat;
mSamples = supportedSamples;
mActualFormat = d3d9_gl::GetInternalFormat(renderFormat);
mActualFormat = d3dFormatInfo.internalFormat;
}
RenderTarget9::~RenderTarget9()
......
......@@ -352,8 +352,6 @@ EGLint Renderer9::initialize()
initializeDevice();
d3d9::InitializeVertexTranslations(this);
return EGL_SUCCESS;
}
......@@ -419,40 +417,24 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList)
for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
{
D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
if (SUCCEEDED(result))
const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]);
const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
if (renderTargetFormatCaps.renderable)
{
for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
{
D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
HRESULT result = D3D_OK;
if(depthStencilFormat != D3DFMT_UNKNOWN)
{
result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
}
if (SUCCEEDED(result))
const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]);
const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN)
{
if(depthStencilFormat != D3DFMT_UNKNOWN)
{
result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
}
if (SUCCEEDED(result))
{
ConfigDesc 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;
}
ConfigDesc newConfig;
newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]);
newConfig.es3Capable = false;
(*configDescList)[numConfigs++] = newConfig;
}
}
}
......@@ -2763,7 +2745,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
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)
{
// Direct copy possible
......@@ -2775,9 +2758,12 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
}
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::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type);
if (fastCopyFunc)
{
// Fast copy is possible through some special function
......@@ -2794,8 +2780,6 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
}
else
{
ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format);
gl::ColorF temp;
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
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
readFunc(src, &temp);
sourceD3DFormatInfo.colorReadFunction(src, &temp);
destFormatTypeInfo.colorWriteFunction(&temp, dest);
}
}
......@@ -3100,13 +3084,12 @@ bool Renderer9::getLUID(LUID *adapterLuid) 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
{
D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat);
return d3d9::GetDeclTypeComponentType(declType);
return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType;
}
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
pShareHandle = &mShareHandle;
}
const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat);
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
gl_d3d9::GetTextureFormat(mBackBufferFormat),
D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
pShareHandle);
if (FAILED(result))
{
ERR("Could not create offscreen texture: %08lX", result);
......@@ -150,12 +151,14 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(oldRenderTarget);
}
const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat);
if (mWindow)
{
D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat);
presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
presentParameters.BackBufferCount = 1;
presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat);
presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
presentParameters.hDeviceWindow = mWindow;
......@@ -207,7 +210,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
if (mDepthBufferFormat != GL_NONE)
{
result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
gl_d3d9::GetRenderFormat(mDepthBufferFormat),
depthBufferd3dFormatInfo.renderFormat,
D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);
if (FAILED(result))
......
......@@ -44,11 +44,12 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget)
DWORD d3dusage = 0;
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
d3dusage |= D3DUSAGE_DEPTHSTENCIL;
}
else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN))
else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN))
{
d3dusage |= D3DUSAGE_RENDERTARGET;
}
......@@ -107,11 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat
if (width > 0 && height > 0)
{
IDirect3DDevice9 *device = mRenderer->getDevice();
D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat);
d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
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))
{
......@@ -208,11 +209,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo
{
IDirect3DDevice9 *device = mRenderer->getDevice();
int height = size;
D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat);
d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
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))
{
......
......@@ -19,7 +19,7 @@
namespace rx
{
VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer)
VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer)
{
mVertexBuffer = NULL;
mBufferSize = 0;
......@@ -117,7 +117,8 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con
}
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)
{
......@@ -126,8 +127,7 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, con
}
else
{
VertexCopyFunction copyFunction = d3d9::GetVertexCopyFunction(vertexFormat);
copyFunction(input, inputStride, count, mapPtr);
d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
}
mVertexBuffer->Unlock();
......@@ -200,10 +200,10 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
}
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);
unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat);
const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat);
if (attrib.enabled)
{
......@@ -218,11 +218,11 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t
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)
{
*outSpaceRequired = elementSize * elementCount;
*outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount;
}
return true;
}
......
......@@ -18,7 +18,7 @@ class Renderer9;
class VertexBuffer9 : public VertexBuffer
{
public:
explicit VertexBuffer9(rx::Renderer9 *const renderer);
explicit VertexBuffer9(rx::Renderer9 *renderer);
virtual ~VertexBuffer9();
virtual bool initialize(unsigned int size, bool dynamicUsage);
......@@ -39,14 +39,14 @@ class VertexBuffer9 : public VertexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
rx::Renderer9 *const mRenderer;
rx::Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mBufferSize;
bool mDynamicUsage;
static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired);
bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired) const;
};
}
......
......@@ -74,6 +74,9 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
}
}
D3DCAPS9 caps;
device->GetDeviceCaps(&caps);
D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
......@@ -133,10 +136,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
}
gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT);
const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat);
element->Stream = stream;
element->Offset = 0;
element->Type = d3d9::GetNativeVertexFormat(vertexFormat);
element->Type = d3d9VertexInfo.nativeFormat;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
element->UsageIndex = programBinary->getSemanticIndex(i);
......
......@@ -18,255 +18,134 @@
namespace rx
{
// 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
// 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)
namespace d3d9
{
UNREACHABLE();
}
const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
struct D3D9FormatInfo
struct D3D9FastCopyFormat
{
D3DFORMAT mTexFormat;
D3DFORMAT mRenderFormat;
LoadImageFunction mLoadFunction;
GLenum destFormat;
GLenum destType;
ColorCopyFunction copyFunction;
D3D9FormatInfo()
: mTexFormat(D3DFMT_NULL), mRenderFormat(D3DFMT_NULL), mLoadFunction(NULL)
D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction)
: destFormat(destFormat), destType(destType), copyFunction(copyFunction)
{ }
D3D9FormatInfo(D3DFORMAT textureFormat, D3DFORMAT renderFormat, LoadImageFunction loadFunc)
: mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc)
{ }
bool operator<(const D3D9FastCopyFormat& other) const
{
return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0;
}
};
typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair;
typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap;
typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap;
static D3D9FormatMap BuildD3D9FormatMap()
static D3D9FastCopyMap BuildFastCopyMap()
{
D3D9FormatMap map;
D3D9FastCopyMap map;
// | Internal format | Texture format | Render format | Load function |
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> )));
map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRAUByteToRGBAUByte)));
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
struct D3DFormatInfo
ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const
{
GLuint mPixelBits;
GLuint mBlockWidth;
GLuint mBlockHeight;
GLenum mInternalFormat;
MipGenerationFunction mMipGenerationFunction;
ColorReadFunction mColorReadFunction;
FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
}
D3DFormatInfo()
: mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL),
mColorReadFunction(NULL)
{ }
static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth,
GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc,
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,
MipGenerationFunction mipFunc, ColorReadFunction readFunc)
: mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat),
mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc)
{ }
};
static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format);
for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
{
info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
}
typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair;
typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap;
map->insert(std::make_pair(format, info));
}
static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
{
D3D9FormatInfoMap map;
// | 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 )));
map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL )));
map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_R16F, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 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> )));
map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F, D3DFormatInfo( 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>)));
map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL )));
map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL )));
map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL )));
map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL )));
map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 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 )));
map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(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 )));
// | D3DFORMAT | S |W |H | Internal format | Mip generation function | Color read function |
InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, GL_NONE, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> );
InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL );
InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL );
return map;
}
static const D3D9FormatInfoMap &GetD3D9FormatInfoMap()
const D3DFormat &GetD3DFormatInfo(D3DFORMAT format)
{
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);
if (iter != infoMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
return iter->second;
}
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::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
......@@ -275,160 +154,139 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
{
InternalFormatInitialzerMap map;
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_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>));
map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
return map;
}
static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap()
{
static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap();
return map;
}
// 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
// in templates that perform format support queries on a Renderer9 object which is supplied
// 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 (GetD3D9FormatInfo(format, &d3dFormatInfo))
if (pred())
{
return d3dFormatInfo.mMipGenerationFunction;
prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
}
else
{
UNREACHABLE();
return NULL;
fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
}
}
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;
if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mLoadFunction;
}
else
{
UNREACHABLE();
return NULL;
}
UNREACHABLE();
}
GLuint GetFormatPixelBytes(D3DFORMAT format)
{
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mPixelBits / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
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;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mBlockHeight;
}
else
{
UNREACHABLE();
return 0;
}
}
TextureFormat info;
info.texFormat = texFormat;
info.renderFormat = renderFormat;
GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height)
{
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth;
GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight;
static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap();
InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat);
info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL;
return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
}
else
{
UNREACHABLE();
return 0;
}
info.loadFunction = loadFunction;
map->insert(std::make_pair(internalFormat, info));
}
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
static D3D9FormatMap BuildD3D9FormatMap()
{
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
{
int upsampleCount = 0;
D3D9FormatMap map;
GLsizei blockWidth = d3dFormatInfo.mBlockWidth;
GLsizei blockHeight = d3dFormatInfo.mBlockHeight;
// | Internal format | Texture format | Render format | Load function |
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.
if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
{
while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
{
*requestWidth <<= 1;
*requestHeight <<= 1;
upsampleCount++;
}
}
*levelOffset = upsampleCount;
}
}
// These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
// then changing the format and loading function appropriately.
InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> );
InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> );
const D3DFormatSet &GetAllUsedD3DFormats()
{
static const D3DFormatSet formatSet = BuildAllD3DFormatSet();
return formatSet;
return map;
}
ColorReadFunction GetColorReadFunction(D3DFORMAT format)
const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
{
D3DFormatInfo d3dFormatInfo;
if (GetD3D9FormatInfo(format, &d3dFormatInfo))
static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
return d3dFormatInfo.mColorReadFunction;
return iter->second;
}
else
{
UNREACHABLE();
return NULL;
static const TextureFormat defaultInfo;
return defaultInfo;
}
}
ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType)
{
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)
static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
{
switch (declType)
{
......@@ -451,27 +309,13 @@ GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
// Attribute format conversion
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
{
DWORD capsFlag;
FormatConverter preferredConversion;
FormatConverter fallbackConversion;
VertexFormat preferredConversion;
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:
//
// BYTE SHORT (Cast)
......@@ -623,14 +467,35 @@ public:
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
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) \
{ \
CreateVertexFormatInfo \
( \
Converter<type, norm, size, preferred>::identity, \
Converter<type, norm, size, preferred>::finalSize, \
Converter<type, norm, size, preferred>::convertArray, \
static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
}
)
#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
{ \
......@@ -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) }, \
}
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),
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)
};
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;
void InitializeVertexTranslations(const rx::Renderer9 *renderer)
{
DWORD declTypes = renderer->getCapsDeclTypes();
default: UNREACHABLE(); return 5;
}
}
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)
{
mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
}
else
for (unsigned int k = 0; k < 4; k++)
{
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
ASSERT(!vertexFormat.mPureInteger);
return mFormatConverters[typeIndex(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;
return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1];
}
}
......
......@@ -20,55 +20,50 @@ class Renderer9;
namespace d3d9
{
typedef std::set<D3DFORMAT> D3DFormatSet;
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format);
LoadImageFunction GetImageLoadFunction(GLenum internalFormat);
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);
struct D3DFormat
{
D3DFormat();
VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat);
size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat);
VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat);
D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat);
GLuint pixelBytes;
GLuint blockWidth;
GLuint blockHeight;
GLenum GetDeclTypeComponentType(D3DDECLTYPE declType);
int GetDeclTypeComponentCount(D3DDECLTYPE declType);
bool IsDeclTypeNormalized(D3DDECLTYPE declType);
GLenum internalFormat;
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);
D3DFORMAT GetRenderFormat(GLenum internalFormat);
VertexConversionType conversionType;
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);
InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat);
D3DFORMAT texFormat;
D3DFORMAT renderFormat;
}
namespace d3d9_gl
{
InitializeTextureDataFunction dataInitializerFunction;
GLenum GetInternalFormat(D3DFORMAT format);
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
LoadImageFunction loadFunction;
};
const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
}
......
......@@ -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
{
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,
UINT adapter, D3DFORMAT adapterFormat)
{
gl::TextureCaps textureCaps;
D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat);
gl::InternalFormat formatInfo = gl::GetInternalFormatInfo(internalFormat);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, renderFormat));
textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, renderFormat));
textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, renderFormat)) ||
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, 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, d3dFormatInfo.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, d3dFormatInfo.renderFormat));
}
else
{
D3DFORMAT textureFormat = gl_d3d9::GetTextureFormat(internalFormat);
textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, textureFormat)) &&
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, textureFormat));
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, textureFormat)) ||
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, textureFormat));
textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) &&
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat));
textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) ||
SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
}
textureCaps.sampleCounts.insert(1);
......@@ -280,7 +296,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3
{
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))
{
textureCaps.sampleCounts.insert(i);
......@@ -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);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
}
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,
gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
......@@ -44,6 +50,10 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
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)
{
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