Commit 511937d9 by JiangYizhou Committed by Commit Bot

ES3.1: Implement framebuffer default parameters for d3d part.

Set framebuffer default params with glFramebufferParameteri and glGetFramebufferParameteriv, keep framebuffer default parameters in cache for query. The es 3.1 spec section 9.2 states that, "If there are no attachments , rendering will be limited to a rectangle having a lower left of (0, 0) and an upper right of (width, height), where width and height are the framebuffer object's default width and height." If the Framebuffer has no color attachment and the default width or height is smaller than the current viewport, use the smaller of the two sizes. BUG=angleproject:1594 TEST=dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default* TEST=dEQP-GLES31.functional.fbo.completeness.no_attachments TEST=dEQP-GLES31.functional.fbo.no_attachments.* TEST=angle_end2end_tests --gtest_filter=FramebufferTest_ES31.* Change-Id: I8041fd655161390acf115efa08ce0f04b10810a0 Reviewed-on: https://chromium-review.googlesource.com/609414 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d27f5c8d
......@@ -8,19 +8,20 @@
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "common/debug.h"
#include "common/bitset_utils.h"
#include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Texture.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Texture.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
using namespace angle;
......@@ -413,6 +414,11 @@ void Framebuffer11::syncState(const gl::Context *context,
case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
break;
case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
break;
default:
{
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
......@@ -432,6 +438,12 @@ void Framebuffer11::syncState(const gl::Context *context,
// Call this last to allow the state manager to take advantage of the cached render targets.
mRenderer->getStateManager()->invalidateRenderTarget(context);
// Call this to syncViewport for framebuffer default parameters.
if (mState.getDefaultWidth() != 0 || mState.getDefaultHeight() != 0)
{
mRenderer->getStateManager()->invalidateViewport(context);
}
}
void Framebuffer11::signal(size_t channelID)
......
......@@ -860,16 +860,16 @@ void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool ena
mCurScissorEnabled = enabled;
}
void StateManager11::syncViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar)
void StateManager11::syncViewport(const gl::Context *context)
{
float actualZNear = gl::clamp01(zNear);
float actualZFar = gl::clamp01(zFar);
const auto &glState = context->getGLState();
gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
float actualZNear = gl::clamp01(glState.getNearPlane());
float actualZFar = gl::clamp01(glState.getFarPlane());
int dxMaxViewportBoundsX = static_cast<int>(caps->maxViewportWidth);
int dxMaxViewportBoundsY = static_cast<int>(caps->maxViewportHeight);
const auto &caps = context->getCaps();
int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
......@@ -882,6 +882,7 @@ void StateManager11::syncViewport(const gl::Caps *caps,
dxMinViewportBoundsY = 0;
}
const auto &viewport = glState.getViewport();
int dxViewportTopLeftX = gl::clamp(viewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
int dxViewportTopLeftY = gl::clamp(viewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
int dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
......@@ -910,6 +911,22 @@ void StateManager11::syncViewport(const gl::Caps *caps,
dxViewport.MinDepth = actualZNear;
dxViewport.MaxDepth = actualZFar;
// The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering
// will be limited to a rectangle having a lower left of (0, 0) and an upper right of
// (width, height), where width and height are the framebuffer object's default width
// and height." See http://anglebug.com/1594
// If the Framebuffer has no color attachment and the default width or height is smaller
// than the current viewport, use the smaller of the two sizes.
// If framebuffer default width or height is 0, the params should not set.
if (!framebuffer->getFirstNonNullAttachment() &&
(framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight()))
{
dxViewport.Width =
static_cast<GLfloat>(std::min(viewport.width, framebuffer->getDefaultWidth()));
dxViewport.Height =
static_cast<GLfloat>(std::min(viewport.height, framebuffer->getDefaultHeight()));
}
mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport);
mCurViewport = viewport;
......@@ -1071,6 +1088,11 @@ void StateManager11::invalidateVertexBuffer()
mInputLayoutIsDirty = true;
}
void StateManager11::invalidateViewport(const gl::Context *context)
{
mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
}
void StateManager11::setOneTimeRenderTarget(const gl::Context *context,
ID3D11RenderTargetView *rtv,
ID3D11DepthStencilView *dsv)
......@@ -1287,7 +1309,7 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
const auto &drawStates = framebuffer->getDrawBufferStates();
gl::DrawBufferMask activeProgramOutputs =
context->getContextState().getState().getProgram()->getActiveOutputVariables();
UINT maxExistingRT = 0;
UINT maxExistingRT = 0;
for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex)
{
......@@ -1317,7 +1339,7 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
// Get the depth stencil buffers
ID3D11DepthStencilView *framebufferDSV = nullptr;
const auto *depthStencilRenderTarget = framebuffer11->getCachedDepthStencilRenderTarget();
const auto *depthStencilRenderTarget = framebuffer11->getCachedDepthStencilRenderTarget();
if (depthStencilRenderTarget)
{
framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get();
......@@ -1503,8 +1525,7 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
ANGLE_TRY(syncFramebuffer(context, framebuffer));
break;
case DIRTY_BIT_VIEWPORT_STATE:
syncViewport(&context->getCaps(), glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane());
syncViewport(context);
break;
case DIRTY_BIT_SCISSOR_STATE:
syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
......
......@@ -115,6 +115,7 @@ class StateManager11 final : angle::NonCopyable
void invalidateBoundViews(const gl::Context *context);
void invalidateVertexBuffer();
void invalidateEverything(const gl::Context *context);
void invalidateViewport(const gl::Context *context);
// Called from VertexArray11::updateVertexAttribStorage.
void invalidateCurrentValueAttrib(size_t attribIndex);
......@@ -199,7 +200,7 @@ class StateManager11 final : angle::NonCopyable
void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled);
void syncViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar);
void syncViewport(const gl::Context *context);
void checkPresentPath(const gl::Context *context);
......
......@@ -1058,6 +1058,31 @@ size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)
}
}
size_t GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
// REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9,
// use the maximum texture sizes
case D3D_FEATURE_LEVEL_9_3:
return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1:
return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
default:
UNREACHABLE();
return 0;
}
}
IntelDriverVersion GetIntelDriverVersion(const Optional<LARGE_INTEGER> driverVersion)
{
if (!driverVersion.valid())
......@@ -1328,6 +1353,12 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max();
caps->maxIntegerSamples = std::numeric_limits<GLint>::max();
// Framebuffer limits
caps->maxFramebufferSamples = std::numeric_limits<GLint>::max();
caps->maxFramebufferWidth =
static_cast<GLuint>(GetMaximumRenderToBufferWindowSize(featureLevel));
caps->maxFramebufferHeight = caps->maxFramebufferWidth;
// GL extension support
extensions->setTextureExtensionSupport(*textureCapsMap);
extensions->elementIndexUint = true;
......
......@@ -51,8 +51,6 @@
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_uint_2d_array = FAIL
// D3D11 Failing Tests
1442 D3D11 : dEQP-GLES31.functional.fbo.completeness.no_attachments = FAIL
1442 D3D11 : dEQP-GLES31.functional.fbo.no_attachments.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_color_texture_samples_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_depth_texture_samples_* = FAIL
......@@ -83,10 +81,6 @@
1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_width_get_framebuffer_parameteriv = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_height_get_framebuffer_parameteriv = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_samples_get_framebuffer_parameteriv = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_fixed_sample_locations_get_framebuffer_parameteriv = FAIL
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
......
......@@ -521,6 +521,30 @@ ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENG
class FramebufferTest_ES31 : public ANGLETest
{
protected:
void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
{
glUniform2i(0, width - 1, height - 1);
glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
glDrawArrays(GL_TRIANGLES, 0, 6);
glEndQuery(GL_ANY_SAMPLES_PASSED);
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
EXPECT_GT(static_cast<GLint>(passedCount), 0);
glUniform2i(0, width - 1, height);
glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
glDrawArrays(GL_TRIANGLES, 0, 6);
glEndQuery(GL_ANY_SAMPLES_PASSED);
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
EXPECT_EQ(static_cast<GLint>(passedCount), 0);
glUniform2i(0, width, height - 1);
glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
glDrawArrays(GL_TRIANGLES, 0, 6);
glEndQuery(GL_ANY_SAMPLES_PASSED);
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
EXPECT_EQ(static_cast<GLint>(passedCount), 0);
}
};
// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
......@@ -641,4 +665,90 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
ASSERT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_OPENGL(), ES31_OPENGLES());
// If there are no attachments, rendering will be limited to a rectangle having a lower left of
// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
// object's default width and height.
TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttchments)
{
const std::string &vertexShader =
"#version 310 es\n"
"in layout(location = 0) highp vec2 a_position;\n\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_position, 0.0, 1.0);\n"
"}\n";
const std::string &fragShader =
"#version 310 es\n"
"uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
"out layout(location = 0) mediump vec4 f_color;\n\n"
"void main()\n"
"{\n"
" if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
" f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
"}\n";
GLuint program = CompileProgram(vertexShader, fragShader);
ASSERT_NE(program, 0u);
glUseProgram(program);
GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
GLuint defaultWidth = 1;
GLuint defaultHeight = 1;
glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
const float data[] = {
1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
};
GLuint vertexArray = 0;
GLuint vertexBuffer = 0;
GLuint query = 0;
GLuint passedCount = 0;
glGenQueries(1, &query);
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
// If fbo has attachments, the rendering size should be the same as its attachment.
GLTexture mTexture;
GLuint width = 2;
GLuint height = 2;
glBindTexture(GL_TEXTURE_2D, mTexture.get());
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture.get(),
0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
validateSamplePass(query, passedCount, width, height);
// If fbo's attachment has been removed, the rendering size should be the same as framebuffer
// default size.
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDeleteBuffers(1, &vertexBuffer);
glDeleteVertexArrays(1, &vertexArray);
ASSERT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
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