Commit 54bd5a46 by Geoff Lang

Move blit to the Framebuffer object and Impl.

BUG=angle:841 Change-Id: I482e53a90606d9d6b105c7006234215d51ab1a6b Reviewed-on: https://chromium-review.googlesource.com/232692Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent bce529e4
...@@ -1525,14 +1525,6 @@ size_t Context::getExtensionStringCount() const ...@@ -1525,14 +1525,6 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size(); return mExtensionStrings.size();
} }
Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void Context::initCaps(GLuint clientVersion) void Context::initCaps(GLuint clientVersion)
{ {
mCaps = mRenderer->getRendererCaps(); mCaps = mRenderer->getRendererCaps();
......
...@@ -199,9 +199,6 @@ class Context ...@@ -199,9 +199,6 @@ class Context
const std::string &getExtensionString(size_t idx) const; const std::string &getExtensionString(size_t idx) const;
size_t getExtensionStringCount() const; size_t getExtensionStringCount() const;
Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
rx::Renderer *getRenderer() { return mRenderer; } rx::Renderer *getRenderer() { return mRenderer; }
State &getState() { return mState; } State &getState() { return mState; }
......
...@@ -503,6 +503,12 @@ Error Framebuffer::readPixels(const gl::State &state, const gl::Rectangle &area, ...@@ -503,6 +503,12 @@ Error Framebuffer::readPixels(const gl::State &state, const gl::Rectangle &area,
return mImpl->readPixels(state, area, format, type, pixels); return mImpl->readPixels(state, area, format, type, pixels);
} }
Error Framebuffer::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
{
return mImpl->blit(state, sourceArea, destArea, mask, filter, sourceFramebuffer);
}
int Framebuffer::getSamples(const gl::Data &data) const int Framebuffer::getSamples(const gl::Data &data) const
{ {
if (checkStatus(data) == GL_FRAMEBUFFER_COMPLETE) if (checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
......
...@@ -98,6 +98,9 @@ class Framebuffer ...@@ -98,6 +98,9 @@ class Framebuffer
GLenum getImplementationColorReadType() const; GLenum getImplementationColorReadType() const;
Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const; Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const;
Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer);
// Use this method to retrieve the color buffer map when doing rendering. // Use this method to retrieve the color buffer map when doing rendering.
// It will apply a workaround for poor shader performance on some systems // It will apply a workaround for poor shader performance on some systems
// by compacting the list to skip NULL values. // by compacting the list to skip NULL values.
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace gl namespace gl
{ {
class State; class State;
class Framebuffer;
class FramebufferAttachment; class FramebufferAttachment;
struct Rectangle; struct Rectangle;
} }
...@@ -61,6 +62,9 @@ class FramebufferImpl ...@@ -61,6 +62,9 @@ class FramebufferImpl
virtual GLenum getImplementationColorReadType() const = 0; virtual GLenum getImplementationColorReadType() const = 0;
virtual gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const = 0; virtual gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const = 0;
virtual gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) = 0;
virtual GLenum checkStatus() const = 0; virtual GLenum checkStatus() const = 0;
}; };
......
...@@ -84,11 +84,6 @@ class Renderer ...@@ -84,11 +84,6 @@ class Renderer
const GLvoid *indices, GLsizei instances, const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange) = 0; const RangeUI &indexRange) = 0;
virtual gl::Error blitFramebuffer(const gl::Data &data,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) = 0;
// TODO(jmadill): caps? and virtual for egl::Display // TODO(jmadill): caps? and virtual for egl::Display
virtual bool getShareHandleSupport() const = 0; virtual bool getShareHandleSupport() const = 0;
virtual bool getPostSubBufferSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "libANGLE/renderer/d3d/RenderbufferD3D.h" #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
#include "libANGLE/renderer/RenderTarget.h" #include "libANGLE/renderer/RenderTarget.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
namespace rx namespace rx
...@@ -252,6 +253,47 @@ gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle ...@@ -252,6 +253,47 @@ gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle
return readPixels(area, format, type, outputPitch, state.getPackState(), reinterpret_cast<uint8_t*>(pixels)); return readPixels(area, format, type, outputPitch, state.getPackState(), reinterpret_cast<uint8_t*>(pixels));
} }
gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
{
bool blitRenderTarget = false;
if ((mask & GL_COLOR_BUFFER_BIT) &&
sourceFramebuffer->getReadColorbuffer() != nullptr &&
std::any_of(mColorBuffers.begin(), mColorBuffers.end(), [](const gl::FramebufferAttachment* attachment){ return attachment != nullptr; }))
{
blitRenderTarget = true;
}
bool blitStencil = false;
if ((mask & GL_STENCIL_BUFFER_BIT) &&
sourceFramebuffer->getStencilbuffer() != nullptr &&
mStencilbuffer != nullptr)
{
blitStencil = true;
}
bool blitDepth = false;
if ((mask & GL_DEPTH_BUFFER_BIT) &&
sourceFramebuffer->getDepthbuffer() != nullptr &&
mDepthbuffer != nullptr)
{
blitDepth = true;
}
if (blitRenderTarget || blitDepth || blitStencil)
{
const gl::Rectangle *scissor = state.isScissorTestEnabled() ? &state.getScissor() : NULL;
gl::Error error = blit(sourceArea, destArea, scissor, blitRenderTarget, blitDepth, blitStencil,
filter, sourceFramebuffer);
if (error.isError())
{
return error;
}
}
return gl::Error(GL_NO_ERROR);
}
GLenum FramebufferD3D::checkStatus() const GLenum FramebufferD3D::checkStatus() const
{ {
// D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
......
...@@ -73,6 +73,9 @@ class FramebufferD3D : public FramebufferImpl ...@@ -73,6 +73,9 @@ class FramebufferD3D : public FramebufferImpl
GLenum getImplementationColorReadType() const override; GLenum getImplementationColorReadType() const override;
gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const override; gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const override;
gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) override;
GLenum checkStatus() const override; GLenum checkStatus() const override;
protected: protected:
...@@ -90,6 +93,10 @@ class FramebufferD3D : public FramebufferImpl ...@@ -90,6 +93,10 @@ class FramebufferD3D : public FramebufferImpl
virtual gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, virtual gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
const gl::PixelPackState &pack, uint8_t *pixels) const = 0; const gl::PixelPackState &pack, uint8_t *pixels) const = 0;
virtual gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer) = 0;
}; };
gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget **outRT); gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget **outRT);
......
...@@ -636,46 +636,6 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) ...@@ -636,46 +636,6 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
return mIncompleteTextures[type].get(); return mIncompleteTextures[type].get();
} }
gl::Error RendererD3D::blitFramebuffer(const gl::Data &data,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
const gl::Framebuffer *readFramebuffer = data.state->getReadFramebuffer();
const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
bool blitRenderTarget = false;
bool blitDepth = false;
bool blitStencil = false;
if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
{
blitRenderTarget = true;
}
if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{
blitStencil = true;
}
if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{
blitDepth = true;
}
gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
if (blitRenderTarget || blitDepth || blitStencil)
{
const gl::Rectangle *scissor = data.state->isScissorTestEnabled() ? &data.state->getScissor() : NULL;
gl::Error error = blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
blitRenderTarget, blitDepth, blitStencil, filter);
if (error.isError())
{
return error;
}
}
return gl::Error(GL_NO_ERROR);
}
bool RendererD3D::isDeviceLost() const bool RendererD3D::isDeviceLost() const
{ {
return mDeviceLost; return mDeviceLost;
......
...@@ -59,11 +59,6 @@ class RendererD3D : public Renderer ...@@ -59,11 +59,6 @@ class RendererD3D : public Renderer
const GLvoid *indices, GLsizei instances, const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange) override; const RangeUI &indexRange) override;
gl::Error blitFramebuffer(const gl::Data &data,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) override;
bool isDeviceLost() const override; bool isDeviceLost() const override;
std::string getVendorString() const override; std::string getVendorString() const override;
...@@ -164,10 +159,6 @@ class RendererD3D : public Renderer ...@@ -164,10 +159,6 @@ class RendererD3D : public Renderer
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget,
bool blitDepth, bool blitStencil, GLenum filter) = 0;
virtual bool getLUID(LUID *adapterLuid) const = 0; virtual bool getLUID(LUID *adapterLuid) const = 0;
......
...@@ -146,4 +146,83 @@ gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GL ...@@ -146,4 +146,83 @@ gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GL
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer)
{
if (blitRenderTarget)
{
const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorbuffer();
ASSERT(readBuffer);
RenderTarget *readRenderTarget = NULL;
gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
for (size_t colorAttachment = 0; colorAttachment < mDrawBuffers.size(); colorAttachment++)
{
if (mColorBuffers[colorAttachment] != nullptr && mDrawBuffers[colorAttachment] != GL_NONE)
{
const gl::FramebufferAttachment *drawBuffer = mColorBuffers[colorAttachment];
RenderTarget *drawRenderTarget = NULL;
error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget,
filter, scissor, blitRenderTarget, false, false);
if (error.isError())
{
return error;
}
}
}
}
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
ASSERT(readBuffer);
RenderTarget *readRenderTarget = NULL;
gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
const gl::FramebufferAttachment *drawBuffer = (mDepthbuffer != nullptr) ? mDepthbuffer
: mStencilbuffer;
ASSERT(drawBuffer);
RenderTarget *drawRenderTarget = NULL;
error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget, filter, scissor,
false, blitDepth, blitStencil);
if (error.isError())
{
return error;
}
}
invalidateSwizzles();
return gl::Error(GL_NO_ERROR);
}
} }
...@@ -30,6 +30,10 @@ class Framebuffer11 : public FramebufferD3D ...@@ -30,6 +30,10 @@ class Framebuffer11 : public FramebufferD3D
gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
const gl::PixelPackState &pack, uint8_t *pixels) const override; const gl::PixelPackState &pack, uint8_t *pixels) const override;
gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer) override;
Renderer11 *const mRenderer; Renderer11 *const mRenderer;
}; };
......
...@@ -2736,86 +2736,6 @@ gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack ...@@ -2736,86 +2736,6 @@ gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack
return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
} }
gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget,
bool blitDepth, bool blitStencil, GLenum filter)
{
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
ASSERT(readBuffer);
RenderTarget *readRenderTarget = NULL;
gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
if (drawTarget->isEnabledColorAttachment(colorAttachment))
{
gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
ASSERT(drawBuffer);
RenderTarget *drawRenderTarget = NULL;
error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget,
false, false);
if (error.isError())
{
return error;
}
}
}
}
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
ASSERT(readBuffer);
RenderTarget *readRenderTarget = NULL;
gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
ASSERT(drawBuffer);
RenderTarget *drawRenderTarget = NULL;
error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false,
blitDepth, blitStencil);
if (error.isError())
{
return error;
}
}
invalidateFramebufferSwizzles(drawTarget);
return gl::Error(GL_NO_ERROR);
}
Image *Renderer11::createImage() Image *Renderer11::createImage()
{ {
return new Image11(); return new Image11();
......
...@@ -127,9 +127,6 @@ class Renderer11 : public RendererD3D ...@@ -127,9 +127,6 @@ class Renderer11 : public RendererD3D
virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override;
// RenderTarget creation // RenderTarget creation
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT); virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
...@@ -210,6 +207,10 @@ class Renderer11 : public RendererD3D ...@@ -210,6 +207,10 @@ class Renderer11 : public RendererD3D
void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv); void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit);
bool isES3Capable() const { return mFeatureLevel >= D3D_FEATURE_LEVEL_10_0; }; bool isES3Capable() const { return mFeatureLevel >= D3D_FEATURE_LEVEL_10_0; };
D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }; D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; };
...@@ -222,9 +223,6 @@ class Renderer11 : public RendererD3D ...@@ -222,9 +223,6 @@ class Renderer11 : public RendererD3D
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
void unsetConflictingSRVs(gl::SamplerType shaderType, const ID3D11Resource *resource, const gl::ImageIndex *index); void unsetConflictingSRVs(gl::SamplerType shaderType, const ID3D11Resource *resource, const gl::ImageIndex *index);
......
...@@ -227,4 +227,187 @@ gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLe ...@@ -227,4 +227,187 @@ gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLe
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer)
{
ASSERT(filter == GL_NEAREST);
IDirect3DDevice9 *device = mRenderer->getDevice();
ASSERT(device);
mRenderer->endScene();
if (blitRenderTarget)
{
const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorbuffer(0);
ASSERT(readBuffer);
RenderTarget9 *readRenderTarget = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
const gl::FramebufferAttachment *drawBuffer = mColorBuffers[0];
ASSERT(drawBuffer);
RenderTarget9 *drawRenderTarget = NULL;
error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
// The getSurface calls do an AddRef so save them until after no errors are possible
IDirect3DSurface9* readSurface = readRenderTarget->getSurface();
ASSERT(readSurface);
IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface();
ASSERT(drawSurface);
gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
RECT srcRect;
srcRect.left = sourceArea.x;
srcRect.right = sourceArea.x + sourceArea.width;
srcRect.top = sourceArea.y;
srcRect.bottom = sourceArea.y + sourceArea.height;
RECT dstRect;
dstRect.left = destArea.x;
dstRect.right = destArea.x + destArea.width;
dstRect.top = destArea.y;
dstRect.bottom = destArea.y + destArea.height;
// Clip the rectangles to the scissor rectangle
if (scissor)
{
if (dstRect.left < scissor->x)
{
srcRect.left += (scissor->x - dstRect.left);
dstRect.left = scissor->x;
}
if (dstRect.top < scissor->y)
{
srcRect.top += (scissor->y - dstRect.top);
dstRect.top = scissor->y;
}
if (dstRect.right > scissor->x + scissor->width)
{
srcRect.right -= (dstRect.right - (scissor->x + scissor->width));
dstRect.right = scissor->x + scissor->width;
}
if (dstRect.bottom > scissor->y + scissor->height)
{
srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height));
dstRect.bottom = scissor->y + scissor->height;
}
}
// Clip the rectangles to the destination size
if (dstRect.left < 0)
{
srcRect.left += -dstRect.left;
dstRect.left = 0;
}
if (dstRect.right > dstSize.width)
{
srcRect.right -= (dstRect.right - dstSize.width);
dstRect.right = dstSize.width;
}
if (dstRect.top < 0)
{
srcRect.top += -dstRect.top;
dstRect.top = 0;
}
if (dstRect.bottom > dstSize.height)
{
srcRect.bottom -= (dstRect.bottom - dstSize.height);
dstRect.bottom = dstSize.height;
}
// Clip the rectangles to the source size
if (srcRect.left < 0)
{
dstRect.left += -srcRect.left;
srcRect.left = 0;
}
if (srcRect.right > srcSize.width)
{
dstRect.right -= (srcRect.right - srcSize.width);
srcRect.right = srcSize.width;
}
if (srcRect.top < 0)
{
dstRect.top += -srcRect.top;
srcRect.top = 0;
}
if (srcRect.bottom > srcSize.height)
{
dstRect.bottom -= (srcRect.bottom - srcSize.height);
srcRect.bottom = srcSize.height;
}
HRESULT result = device->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
SafeRelease(readSurface);
SafeRelease(drawSurface);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
if (blitDepth || blitStencil)
{
const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
ASSERT(readBuffer);
RenderTarget9 *readDepthStencil = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
if (error.isError())
{
return error;
}
ASSERT(readDepthStencil);
const gl::FramebufferAttachment *drawBuffer = (mDepthbuffer != nullptr) ? mDepthbuffer
: mStencilbuffer;
ASSERT(drawBuffer);
RenderTarget9 *drawDepthStencil = NULL;
error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
if (error.isError())
{
return error;
}
ASSERT(drawDepthStencil);
// The getSurface calls do an AddRef so save them until after no errors are possible
IDirect3DSurface9* readSurface = readDepthStencil->getSurface();
ASSERT(readDepthStencil);
IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface();
ASSERT(drawDepthStencil);
HRESULT result = device->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
SafeRelease(readSurface);
SafeRelease(drawSurface);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
return gl::Error(GL_NO_ERROR);
}
} }
...@@ -27,6 +27,10 @@ class Framebuffer9 : public FramebufferD3D ...@@ -27,6 +27,10 @@ class Framebuffer9 : public FramebufferD3D
gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
const gl::PixelPackState &pack, uint8_t *pixels) const override; const gl::PixelPackState &pack, uint8_t *pixels) const override;
gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer) override;
Renderer9 *const mRenderer; Renderer9 *const mRenderer;
}; };
......
...@@ -2453,186 +2453,6 @@ gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Re ...@@ -2453,186 +2453,6 @@ gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Re
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect,
const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget,
bool blitDepth, bool blitStencil, GLenum filter)
{
ASSERT(filter == GL_NEAREST);
endScene();
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0);
ASSERT(readBuffer);
RenderTarget9 *readRenderTarget = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
ASSERT(drawBuffer);
RenderTarget9 *drawRenderTarget = NULL;
error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
// The getSurface calls do an AddRef so save them until after no errors are possible
IDirect3DSurface9* readSurface = readRenderTarget->getSurface();
ASSERT(readSurface);
IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface();
ASSERT(drawSurface);
gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
RECT srcRect;
srcRect.left = readRect.x;
srcRect.right = readRect.x + readRect.width;
srcRect.top = readRect.y;
srcRect.bottom = readRect.y + readRect.height;
RECT dstRect;
dstRect.left = drawRect.x;
dstRect.right = drawRect.x + drawRect.width;
dstRect.top = drawRect.y;
dstRect.bottom = drawRect.y + drawRect.height;
// Clip the rectangles to the scissor rectangle
if (scissor)
{
if (dstRect.left < scissor->x)
{
srcRect.left += (scissor->x - dstRect.left);
dstRect.left = scissor->x;
}
if (dstRect.top < scissor->y)
{
srcRect.top += (scissor->y - dstRect.top);
dstRect.top = scissor->y;
}
if (dstRect.right > scissor->x + scissor->width)
{
srcRect.right -= (dstRect.right - (scissor->x + scissor->width));
dstRect.right = scissor->x + scissor->width;
}
if (dstRect.bottom > scissor->y + scissor->height)
{
srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height));
dstRect.bottom = scissor->y + scissor->height;
}
}
// Clip the rectangles to the destination size
if (dstRect.left < 0)
{
srcRect.left += -dstRect.left;
dstRect.left = 0;
}
if (dstRect.right > dstSize.width)
{
srcRect.right -= (dstRect.right - dstSize.width);
dstRect.right = dstSize.width;
}
if (dstRect.top < 0)
{
srcRect.top += -dstRect.top;
dstRect.top = 0;
}
if (dstRect.bottom > dstSize.height)
{
srcRect.bottom -= (dstRect.bottom - dstSize.height);
dstRect.bottom = dstSize.height;
}
// Clip the rectangles to the source size
if (srcRect.left < 0)
{
dstRect.left += -srcRect.left;
srcRect.left = 0;
}
if (srcRect.right > srcSize.width)
{
dstRect.right -= (srcRect.right - srcSize.width);
srcRect.right = srcSize.width;
}
if (srcRect.top < 0)
{
dstRect.top += -srcRect.top;
srcRect.top = 0;
}
if (srcRect.bottom > srcSize.height)
{
dstRect.bottom -= (srcRect.bottom - srcSize.height);
srcRect.bottom = srcSize.height;
}
HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
SafeRelease(readSurface);
SafeRelease(drawSurface);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
ASSERT(readBuffer);
RenderTarget9 *readDepthStencil = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
if (error.isError())
{
return error;
}
ASSERT(readDepthStencil);
gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
ASSERT(drawBuffer);
RenderTarget9 *drawDepthStencil = NULL;
error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
if (error.isError())
{
return error;
}
ASSERT(drawDepthStencil);
// The getSurface calls do an AddRef so save them until after no errors are possible
IDirect3DSurface9* readSurface = readDepthStencil->getSurface();
ASSERT(readDepthStencil);
IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface();
ASSERT(drawDepthStencil);
HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
SafeRelease(readSurface);
SafeRelease(drawSurface);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
{ {
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
......
...@@ -136,11 +136,6 @@ class Renderer9 : public RendererD3D ...@@ -136,11 +136,6 @@ class Renderer9 : public RendererD3D
virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget,
bool blitDepth, bool blitStencil, GLenum filter) override;
// RenderTarget creation // RenderTarget creation
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT); virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
......
...@@ -686,8 +686,16 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi ...@@ -686,8 +686,16 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
return; return;
} }
Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
mask, filter); ASSERT(readFramebuffer);
Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
ASSERT(drawFramebuffer);
Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer);
if (error.isError()) if (error.isError())
{ {
context->recordError(error); context->recordError(error);
......
...@@ -767,8 +767,16 @@ void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr ...@@ -767,8 +767,16 @@ void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr
return; return;
} }
Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
mask, filter); ASSERT(readFramebuffer);
Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
ASSERT(drawFramebuffer);
Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer);
if (error.isError()) if (error.isError())
{ {
context->recordError(error); context->recordError(error);
......
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