Commit 34256ed8 by Geoff Lang

Image and RenderTarget classes now initialize their textures if required.

Change-Id: I2cce6f4ffdc7e2a6c23c50d663c6316f9b125880 Reviewed-on: https://chromium-review.googlesource.com/176854Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Commit-Queue: Shannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent 0c99b1b0
...@@ -23,6 +23,7 @@ Image::Image() ...@@ -23,6 +23,7 @@ Image::Image()
mActualFormat = GL_NONE; mActualFormat = GL_NONE;
mTarget = GL_NONE; mTarget = GL_NONE;
mRenderable = false; mRenderable = false;
mDirty = false;
} }
} }
...@@ -81,7 +81,9 @@ void Image11::generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src) ...@@ -81,7 +81,9 @@ void Image11::generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src)
bool Image11::isDirty() const bool Image11::isDirty() const
{ {
return (mStagingTexture && mDirty); // Make sure that this image is marked as dirty even if the staging texture hasn't been created yet
// if initialization is required before use.
return ((mStagingTexture || gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) && mDirty);
} }
bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
...@@ -130,6 +132,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, ...@@ -130,6 +132,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mRenderable = gl_d3d11::GetRTVFormat(internalformat, clientVersion) != DXGI_FORMAT_UNKNOWN; mRenderable = gl_d3d11::GetRTVFormat(internalformat, clientVersion) != DXGI_FORMAT_UNKNOWN;
SafeRelease(mStagingTexture); SafeRelease(mStagingTexture);
mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat);
return true; return true;
} }
...@@ -316,6 +319,7 @@ void Image11::createStagingTexture() ...@@ -316,6 +319,7 @@ void Image11::createStagingTexture()
if (mWidth > 0 && mHeight > 0 && mDepth > 0) if (mWidth > 0 && mHeight > 0 && mDepth > 0)
{ {
ID3D11Device *device = mRenderer->getDevice(); ID3D11Device *device = mRenderer->getDevice();
HRESULT result;
int lodOffset = 1; int lodOffset = 1;
GLsizei width = mWidth; GLsizei width = mWidth;
...@@ -339,7 +343,20 @@ void Image11::createStagingTexture() ...@@ -339,7 +343,20 @@ void Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0; desc.MiscFlags = 0;
HRESULT result = device->CreateTexture3D(&desc, NULL, &newTexture); if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height,
mDepth, lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
}
else
{
result = device->CreateTexture3D(&desc, NULL, &newTexture);
}
if (FAILED(result)) if (FAILED(result))
{ {
ASSERT(result == E_OUTOFMEMORY); ASSERT(result == E_OUTOFMEMORY);
...@@ -367,7 +384,19 @@ void Image11::createStagingTexture() ...@@ -367,7 +384,19 @@ void Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0; desc.MiscFlags = 0;
HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height,
1, lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
}
else
{
result = device->CreateTexture2D(&desc, NULL, &newTexture);
}
if (FAILED(result)) if (FAILED(result))
{ {
......
...@@ -377,6 +377,14 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height ...@@ -377,6 +377,14 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height
return; return;
} }
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
if (gl_d3d11::RequiresTextureDataInitialization(internalFormat))
{
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
context->ClearRenderTargetView(mRenderTarget, clearValues);
}
} }
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
// specific to the D3D11 renderer. // specific to the D3D11 renderer.
#include "libGLESv2/renderer/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d11/formatutils11.h"
#include "common/debug.h" #include "common/debug.h"
namespace rx namespace rx
...@@ -218,6 +218,34 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset) ...@@ -218,6 +218,34 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
namespace d3d11 namespace d3d11
{ {
void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth,
GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
std::vector< std::vector<BYTE> > *outData)
{
InitializeTextureDataFunction initializeFunc = gl_d3d11::GetTextureDataInitializationFunction(internalFormat);
DXGI_FORMAT dxgiFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion);
outSubresourceData->resize(mipLevels);
outData->resize(mipLevels);
for (unsigned int i = 0; i < mipLevels; i++)
{
unsigned int mipWidth = std::max(width >> i, 1U);
unsigned int mipHeight = std::max(height >> i, 1U);
unsigned int mipDepth = std::max(depth >> i, 1U);
unsigned int rowWidth = d3d11::GetFormatPixelBytes(dxgiFormat, clientVersion) * mipWidth;
unsigned int imageSize = rowWidth * height;
outData->at(i).resize(rowWidth * mipHeight * mipDepth);
initializeFunc(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize);
outSubresourceData->at(i).pSysMem = outData->at(i).data();
outSubresourceData->at(i).SysMemPitch = rowWidth;
outSubresourceData->at(i).SysMemSlicePitch = imageSize;
}
}
void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
{ {
vertex->x = x; vertex->x = x;
......
...@@ -39,6 +39,10 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset); ...@@ -39,6 +39,10 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
namespace d3d11 namespace d3d11
{ {
void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth,
GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
std::vector< std::vector<BYTE> > *outData);
struct PositionTexCoordVertex struct PositionTexCoordVertex
{ {
float x, y; float x, y;
......
...@@ -151,6 +151,7 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform ...@@ -151,6 +151,7 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
mRenderable = gl_d3d9::GetRenderFormat(internalformat, mRenderer) != D3DFMT_UNKNOWN; mRenderable = gl_d3d9::GetRenderFormat(internalformat, mRenderer) != D3DFMT_UNKNOWN;
SafeRelease(mSurface); SafeRelease(mSurface);
mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat);
return true; return true;
} }
...@@ -191,6 +192,26 @@ void Image9::createSurface() ...@@ -191,6 +192,26 @@ void Image9::createSurface()
newTexture->GetSurfaceLevel(levelToFetch, &newSurface); newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
SafeRelease(newTexture); SafeRelease(newTexture);
if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat))
{
InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat);
RECT entireRect;
entireRect.left = 0;
entireRect.right = mWidth;
entireRect.top = 0;
entireRect.bottom = mHeight;
D3DLOCKED_RECT lockedRect;
result = newSurface->LockRect(&lockedRect, &entireRect, 0);
ASSERT(SUCCEEDED(result));
initializeFunc(mWidth, mHeight, 1, lockedRect.pBits, lockedRect.Pitch, 0);
result = newSurface->UnlockRect();
ASSERT(SUCCEEDED(result));
}
} }
mSurface = newSurface; mSurface = newSurface;
...@@ -233,6 +254,13 @@ D3DFORMAT Image9::getD3DFormat() const ...@@ -233,6 +254,13 @@ D3DFORMAT Image9::getD3DFormat() const
return mD3DFormat; return mD3DFormat;
} }
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;
}
IDirect3DSurface9 *Image9::getSurface() IDirect3DSurface9 *Image9::getSurface()
{ {
createSurface(); createSurface();
...@@ -670,4 +698,4 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, ...@@ -670,4 +698,4 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
mDirty = true; mDirty = true;
} }
} }
\ No newline at end of file
...@@ -41,7 +41,7 @@ class Image9 : public Image ...@@ -41,7 +41,7 @@ class Image9 : public Image
D3DFORMAT getD3DFormat() const; D3DFORMAT getD3DFormat() const;
virtual bool isDirty() const {return mSurface && mDirty;} virtual bool isDirty() const;
IDirect3DSurface9 *getSurface(); IDirect3DSurface9 *getSurface();
virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); virtual void setManagedSurface(TextureStorageInterface2D *storage, int level);
......
...@@ -62,6 +62,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -62,6 +62,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
{ {
IDirect3DDevice9 *device = mRenderer->getDevice(); IDirect3DDevice9 *device = mRenderer->getDevice();
bool requiresInitialization = false;
if (gl::GetDepthBits(internalFormat, clientVersion) > 0 || if (gl::GetDepthBits(internalFormat, clientVersion) > 0 ||
gl::GetStencilBits(internalFormat, clientVersion) > 0) gl::GetStencilBits(internalFormat, clientVersion) > 0)
{ {
...@@ -71,6 +73,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -71,6 +73,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
} }
else else
{ {
requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat);
result = device->CreateRenderTarget(width, height, renderFormat, result = device->CreateRenderTarget(width, height, renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples), gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL); 0, FALSE, &mRenderTarget, NULL);
...@@ -84,6 +88,18 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, ...@@ -84,6 +88,18 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
} }
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
if (requiresInitialization)
{
// This format requires that the data be initialized before the render target can be used
// Unfortunately this requires a Get call on the d3d device but it is far better than having
// to mark the render target as lockable and copy data to the gpu.
IDirect3DSurface9 *prevRenderTarget = NULL;
device->GetRenderTarget(0, &prevRenderTarget);
device->SetRenderTarget(0, mRenderTarget);
device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
device->SetRenderTarget(0, prevRenderTarget);
}
} }
mWidth = width; mWidth = width;
......
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