Implement larger bounds for viewports and scissor rectangles in D3D11.

This fixes a bug where we would not allow the application to draw outside the viewport, which is valid. TRAC #22497 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1875 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent b3560255
......@@ -251,6 +251,7 @@ void Context::makeCurrent(egl::Surface *surface)
mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
mSupportsInstancing = mRenderer->getInstancingSupport();
mMaxViewportDimension = mRenderer->getMaxViewportDimension();
mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
......@@ -1377,9 +1378,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_MAX_VIEWPORT_DIMS:
{
int maxDimension = std::max(getMaximumRenderbufferDimension(), getMaximumTextureDimension());
params[0] = maxDimension;
params[1] = maxDimension;
params[0] = mMaxViewportDimension;
params[1] = mMaxViewportDimension;
}
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
......
......@@ -485,6 +485,7 @@ class Context
bool mSupportsVertexTexture;
bool mSupportsNonPower2Texture;
bool mSupportsInstancing;
int mMaxViewportDimension;
int mMaxRenderbufferDimension;
int mMaxTextureDimension;
int mMaxCubeTextureDimension;
......
......@@ -169,6 +169,7 @@ class Renderer
virtual int getMajorShaderModel() const = 0;
virtual float getMaxPointSize() const = 0;
virtual int getMaxViewportDimension() const = 0;
virtual int getMaxTextureWidth() const = 0;
virtual int getMaxTextureHeight() const = 0;
virtual bool get32BitIndexSupport() const = 0;
......
......@@ -562,10 +562,10 @@ void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
if (enabled)
{
D3D11_RECT rect;
rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
rect.left = std::max(0, scissor.x);
rect.top = std::max(0, scissor.y);
rect.right = scissor.x + std::max(0, scissor.width);
rect.bottom = scissor.y + std::max(0, scissor.height);
mDeviceContext->RSSetScissorRects(1, &rect);
}
......@@ -598,11 +598,17 @@ bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z
actualZFar = 1.0f;
}
// Get D3D viewport bounds, which depends on the feature level
const Range& viewportBounds = getViewportBounds();
// Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
D3D11_VIEWPORT dxViewport;
dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
dxViewport.MinDepth = actualZNear;
dxViewport.MaxDepth = actualZFar;
......@@ -793,8 +799,8 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
mRenderTargetDesc.width = renderTargetWidth;
mRenderTargetDesc.height = renderTargetHeight;
mRenderTargetDesc.format = renderTargetFormat;
mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
mForceSetViewport = true;
mForceSetScissor = true;
if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
{
......@@ -2023,6 +2029,20 @@ bool Renderer11::getEventQuerySupport()
return true;
}
Range Renderer11::getViewportBounds() const
{
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
default: UNREACHABLE();
return Range(0, 0);
}
}
unsigned int Renderer11::getMaxVertexTextureImageUnits() const
{
META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
......@@ -2160,6 +2180,21 @@ float Renderer11::getMaxPointSize() const
return 1024.0f;
}
int Renderer11::getMaxViewportDimension() const
{
// Clamp viewport width/height to half of the maximum right/bottom edge
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
return D3D11_VIEWPORT_BOUNDS_MAX - D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return D3D10_VIEWPORT_BOUNDS_MAX - D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
default: UNREACHABLE();
return 0;
}
}
int Renderer11::getMaxTextureWidth() const
{
switch (mFeatureLevel)
......
......@@ -21,6 +21,7 @@
#include "common/angleutils.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/RenderStateCache.h"
......@@ -120,6 +121,7 @@ class Renderer11 : public Renderer
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
virtual int getMaxViewportDimension() const;
virtual int getMaxTextureWidth() const;
virtual int getMaxTextureHeight() const;
virtual bool get32BitIndexSupport() const;
......@@ -193,6 +195,7 @@ class Renderer11 : public Renderer
GLint packAlignment, void *pixels);
void maskedClear(const gl::ClearParameters &clearParams);
rx::Range getViewportBounds() const;
bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget,
const gl::Rectangle &drawRect, BlitTarget target);
......
......@@ -2307,6 +2307,13 @@ float Renderer9::getMaxPointSize() const
return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f;
}
int Renderer9::getMaxViewportDimension() const
{
int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
return maxTextureDimension;
}
int Renderer9::getMaxTextureWidth() const
{
return (int)mDeviceCaps.MaxTextureWidth;
......
......@@ -149,6 +149,7 @@ class Renderer9 : public Renderer
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
virtual int getMaxViewportDimension() const;
virtual int getMaxTextureWidth() const;
virtual int getMaxTextureHeight() const;
virtual bool get32BitIndexSupport() const;
......
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