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()
mActualFormat = GL_NONE;
mTarget = GL_NONE;
mRenderable = false;
mDirty = false;
}
}
......@@ -81,7 +81,9 @@ void Image11::generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src)
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)
......@@ -130,6 +132,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mRenderable = gl_d3d11::GetRTVFormat(internalformat, clientVersion) != DXGI_FORMAT_UNKNOWN;
SafeRelease(mStagingTexture);
mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat);
return true;
}
......@@ -316,6 +319,7 @@ void Image11::createStagingTexture()
if (mWidth > 0 && mHeight > 0 && mDepth > 0)
{
ID3D11Device *device = mRenderer->getDevice();
HRESULT result;
int lodOffset = 1;
GLsizei width = mWidth;
......@@ -339,7 +343,20 @@ void Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
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))
{
ASSERT(result == E_OUTOFMEMORY);
......@@ -367,7 +384,19 @@ void Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
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))
{
......
......@@ -377,6 +377,14 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height
return;
}
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 @@
// specific to the D3D11 renderer.
#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d11/formatutils11.h"
#include "common/debug.h"
namespace rx
......@@ -218,6 +218,34 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
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)
{
vertex->x = x;
......
......@@ -39,6 +39,10 @@ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
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
{
float x, y;
......
......@@ -151,6 +151,7 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
mRenderable = gl_d3d9::GetRenderFormat(internalformat, mRenderer) != D3DFMT_UNKNOWN;
SafeRelease(mSurface);
mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat);
return true;
}
......@@ -191,6 +192,26 @@ void Image9::createSurface()
newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
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;
......@@ -233,6 +254,13 @@ D3DFORMAT Image9::getD3DFormat() const
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()
{
createSurface();
......@@ -670,4 +698,4 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
mDirty = true;
}
}
\ No newline at end of file
}
......@@ -41,7 +41,7 @@ class Image9 : public Image
D3DFORMAT getD3DFormat() const;
virtual bool isDirty() const {return mSurface && mDirty;}
virtual bool isDirty() const;
IDirect3DSurface9 *getSurface();
virtual void setManagedSurface(TextureStorageInterface2D *storage, int level);
......
......@@ -62,6 +62,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
{
IDirect3DDevice9 *device = mRenderer->getDevice();
bool requiresInitialization = false;
if (gl::GetDepthBits(internalFormat, clientVersion) > 0 ||
gl::GetStencilBits(internalFormat, clientVersion) > 0)
{
......@@ -71,6 +73,8 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
}
else
{
requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat);
result = device->CreateRenderTarget(width, height, renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &mRenderTarget, NULL);
......@@ -84,6 +88,18 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height,
}
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;
......
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