Make framebuffer DEPTH_STENCIL works well + StencilTexture higher priority. 25/280625/4
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 1 Sep 2022 09:30:14 +0000 (18:30 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 2 Sep 2022 13:38:37 +0000 (22:38 +0900)
Framebuffer cannot attach both Depth and Stencil
at indivisual Renderbuffer.

So, If FrameBuffer::Attachment::Mask::DEPTH_STENCIL used, result is broken.

This patch make if framebuffer try to use both Depth and Stencil,
let Framebuffer use GL_DEPTH_STENCIL_ATTACHMENT.

---

Make stencilTexture has higher proirity than depthTexture in gles case.

Current dali API only have AttachDepthTexture and
AttachDepthStencilTexture.
And, AttachDepthStencilTexture input texture stored in createInfor's
stencilTexture level.

Current device didn't support to seperate each depth/stencil result in gles.
So we need to assume that stencilTexture is depth_stencil texture.

Change-Id: I2a6f46b66c1ef64a6f54e6cc4fc934f0ad276406
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-graphics/CMakeLists.txt
automated-tests/src/dali-graphics/utc-Dali-GraphicsFramebuffer.cpp [new file with mode: 0644]
dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp

index e6416e3..7a31046 100644 (file)
@@ -46,28 +46,32 @@ TestGlAbstraction::~TestGlAbstraction()
 
 void TestGlAbstraction::Initialize()
 {
-  mCurrentProgram                  = 0;
-  mCompileStatus                   = GL_TRUE;
-  mLinkStatus                      = GL_TRUE;
-  mGetErrorResult                  = 0;
-  mGetStringResult                 = NULL;
-  mIsBufferResult                  = 0;
-  mIsEnabledResult                 = 0;
-  mIsFramebufferResult             = 0;
-  mIsProgramResult                 = 0;
-  mIsRenderbufferResult            = 0;
-  mIsShaderResult                  = 0;
-  mIsTextureResult                 = 0;
-  mActiveTextureUnit               = 0;
-  mCheckFramebufferStatusResult    = 0;
-  mFramebufferStatus               = 0;
-  mFramebufferDepthAttached        = 0;
-  mFramebufferStencilAttached      = 0;
-  mFramebufferColorAttachmentCount = 0;
-  mFrameBufferColorStatus          = 0;
-  mNumBinaryFormats                = 0;
-  mBinaryFormats                   = 0;
-  mProgramBinaryLength             = 0;
+  mCurrentProgram                         = 0;
+  mCompileStatus                          = GL_TRUE;
+  mLinkStatus                             = GL_TRUE;
+  mGetErrorResult                         = 0;
+  mGetStringResult                        = NULL;
+  mIsBufferResult                         = 0;
+  mIsEnabledResult                        = 0;
+  mIsFramebufferResult                    = 0;
+  mIsProgramResult                        = 0;
+  mIsRenderbufferResult                   = 0;
+  mIsShaderResult                         = 0;
+  mIsTextureResult                        = 0;
+  mActiveTextureUnit                      = 0;
+  mCheckFramebufferStatusResult           = 0;
+  mFramebufferStatus                      = 0;
+  mFramebufferDepthAttached               = 0;
+  mFramebufferStencilAttached             = 0;
+  mFramebufferDepthStencilAttached        = 0;
+  mFramebufferColorAttachmentCount        = 0;
+  mFrameBufferColorStatus                 = 0;
+  mFramebufferDepthAttachmentCount        = 0;
+  mFramebufferStencilAttachmentCount      = 0;
+  mFramebufferDepthStencilAttachmentCount = 0;
+  mNumBinaryFormats                       = 0;
+  mBinaryFormats                          = 0;
+  mProgramBinaryLength                    = 0;
 
   mVertexAttribArrayChanged = false;
   mGetProgramBinaryCalled   = false;
index a1f8405..f6878ae 100644 (file)
@@ -299,6 +299,21 @@ public:
     return mFramebufferColorAttachmentCount;
   }
 
+  inline GLuint CheckFramebufferDepthAttachmentCount()
+  {
+    return mFramebufferDepthAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferStencilAttachmentCount()
+  {
+    return mFramebufferStencilAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferDepthStencilAttachmentCount()
+  {
+    return mFramebufferDepthStencilAttachmentCount;
+  }
+
   inline GLenum CheckFramebufferDepthAttachment()
   {
     return mFramebufferDepthAttached;
@@ -309,6 +324,11 @@ public:
     return mFramebufferStencilAttached;
   }
 
+  inline GLenum CheckFramebufferDepthStencilAttachment()
+  {
+    return mFramebufferDepthStencilAttached;
+  }
+
   inline void Clear(GLbitfield mask) override
   {
     mClearCount++;
@@ -630,8 +650,9 @@ public:
     }
     else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
     {
-      mFramebufferStencilAttached = true;
-      mFramebufferDepthAttached   = true;
+      mFramebufferStencilAttached      = true;
+      mFramebufferDepthAttached        = true;
+      mFramebufferDepthStencilAttached = true;
     }
   }
 
@@ -650,6 +671,20 @@ public:
         ++mFramebufferColorAttachmentCount;
       }
     }
+    else if(attachment == GL_DEPTH_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+    }
+    else if(attachment == GL_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferStencilAttachmentCount;
+    }
+    else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+      ++mFramebufferStencilAttachmentCount;
+      ++mFramebufferDepthStencilAttachmentCount;
+    }
   }
 
   inline void FrontFace(GLenum mode) override
@@ -2491,8 +2526,12 @@ public:
   GLint                                 mFramebufferStatus;
   GLenum                                mFramebufferDepthAttached;
   GLenum                                mFramebufferStencilAttached;
+  GLenum                                mFramebufferDepthStencilAttached;
   GLuint                                mFramebufferColorAttachmentCount;
   GLuint                                mFrameBufferColorStatus;
+  GLuint                                mFramebufferDepthAttachmentCount;
+  GLuint                                mFramebufferStencilAttachmentCount;
+  GLuint                                mFramebufferDepthStencilAttachmentCount;
   GLint                                 mNumBinaryFormats;
   GLint                                 mBinaryFormats;
   GLint                                 mProgramBinaryLength;
index 639ee31..8a6364e 100644 (file)
@@ -5,10 +5,11 @@ SET(RPM_NAME "core-${PKG_NAME}-tests")
 
 SET(CAPI_LIB "dali-graphics")
 SET(TC_SOURCES
-    utc-Dali-GraphicsSampler.cpp
+    utc-Dali-GraphicsFramebuffer.cpp
     utc-Dali-GraphicsGeometry.cpp
-    utc-Dali-GraphicsProgram.cpp
     utc-Dali-GraphicsNativeImage.cpp
+    utc-Dali-GraphicsProgram.cpp
+    utc-Dali-GraphicsSampler.cpp
 )
 
 LIST(APPEND TC_SOURCES
diff --git a/automated-tests/src/dali-graphics/utc-Dali-GraphicsFramebuffer.cpp b/automated-tests/src/dali-graphics/utc-Dali-GraphicsFramebuffer.cpp
new file mode 100644 (file)
index 0000000..4ba7f19
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali/dali.h>
+
+#include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
+#include <test-actor-utils.h>
+#include <test-graphics-application.h>
+#include <test-graphics-framebuffer.h>
+
+using namespace Dali;
+
+namespace
+{
+RenderTask CreateRenderTask(TestGraphicsApplication& application,
+                            FrameBuffer              framebuffer)
+{
+  Actor rootActor = Actor::New();
+  application.GetScene().Add(rootActor);
+  Texture img         = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Actor   sourceActor = CreateRenderableActor(img);
+  application.GetScene().Add(sourceActor);
+
+  CameraActor offscreenCameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                                           TestApplication::DEFAULT_SURFACE_HEIGHT));
+  application.GetScene().Add(offscreenCameraActor);
+
+  // Change main render task to use a different root
+  RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+  taskList.GetTask(0u).SetSourceActor(rootActor);
+
+  RenderTask newTask = taskList.CreateTask();
+  newTask.SetCameraActor(offscreenCameraActor);
+  newTask.SetSourceActor(sourceActor);
+  newTask.SetInputEnabled(false);
+  newTask.SetClearColor(Vector4(0.f, 0.f, 0.f, 0.f));
+  newTask.SetClearEnabled(true);
+  newTask.SetExclusive(true);
+  newTask.SetFrameBuffer(framebuffer);
+
+  return newTask;
+}
+} // namespace
+
+void utc_dali_graphics_framebuffer_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+void utc_dali_graphics_framebuffer_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliGraphicsFramebufferAttachDepth(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachDepth - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::DEPTH);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Actor   dummyActor        = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsFramebufferAttachStencil(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachStencil - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::STENCIL);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Actor   dummyActor        = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsFramebufferAttachDepthStencil(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachDepthStencil - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::DEPTH_STENCIL);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Actor   dummyActor        = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_TRUE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsFramebufferAttachDepthTexture(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachDepthTexture - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::NONE);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture dummyDepthTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::DEPTH_UNSIGNED_INT, width, height);
+  Actor   dummyActor        = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+  DevelFrameBuffer::AttachDepthTexture(framebuffer, dummyDepthTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsFramebufferAttachDepthStencilTexture(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachDepthStencilTexture - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::STENCIL);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture        = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture dummyDepthStencilTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::DEPTH_STENCIL, width, height);
+  Actor   dummyActor               = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+  DevelFrameBuffer::AttachDepthStencilTexture(framebuffer, dummyDepthStencilTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsFramebufferAttachStencilAndDepthTexture(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliGraphicsFramebufferAttachStencilAndDepthTexture - Test for GLES specific behavior");
+
+  auto& gl = app.GetGlAbstraction();
+
+  uint32_t width  = 16u;
+  uint32_t height = 24u;
+
+  FrameBuffer framebuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::STENCIL);
+
+  DALI_TEST_CHECK(framebuffer);
+
+  Texture dummyColorTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  // Note : Current GLES cannot seperate destination of depth result and stencil result. We need to make the texture as DEPTH_STENCIL
+  Texture dummyDepthTexture = CreateTexture(TextureType::TEXTURE_2D, Pixel::DEPTH_STENCIL, width, height);
+  Actor   dummyActor        = CreateRenderableActor(dummyColorTexture);
+  framebuffer.AttachColorTexture(dummyColorTexture);
+  DevelFrameBuffer::AttachDepthTexture(framebuffer, dummyDepthTexture);
+
+  app.GetScene().Add(dummyActor);
+
+  auto renderTask = CreateRenderTask(app, framebuffer);
+
+  DALI_TEST_CHECK(renderTask);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  DALI_TEST_EQUALS(gl.CheckFramebufferColorAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachmentCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.CheckFramebufferDepthStencilAttachment(), (GLenum)GL_FALSE, TEST_LOCATION); // Check whether renderbuffer attached by DEPTH_STENCIL.
+
+  END_TEST;
+}
\ No newline at end of file
index 2a190b5..f5f750b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -109,31 +109,54 @@ bool Framebuffer::InitializeResource()
     // @todo is this per framebuffer, or more immediate state that needs setting when framebuffer changed?
     context->DrawBuffers(mCreateInfo.colorAttachments.size(), COLOR_ATTACHMENTS);
 
-    if(mCreateInfo.depthStencilAttachment.depthTexture)
+    // @todo Currently, we don't assume that GL_EXT_PACKED_DEPTH_STENCIL valid.
+    // We will assume that stencilTexture / stencilBufferId always mean depth-stencil.
+    if(mCreateInfo.depthStencilAttachment.stencilTexture)
     {
-      // Create a depth or depth/stencil render target.
+      // bind depth 24 bits + stencil 8 bits texture, or 8 tencil texture.
+      auto stencilTexture = static_cast<const GLES::Texture*>(mCreateInfo.depthStencilAttachment.stencilTexture);
+      auto attachmentId   = DEPTH_STENCIL_ATTACHMENT_TYPE(stencilTexture->GetCreateInfo().format).attachment;
+
+      if(attachmentId != GL_DEPTH_STENCIL_ATTACHMENT)
+      {
+        DALI_LOG_ERROR("Current Depth/Stencil Texture Type doesn't support. Please check depth/stencil texture's pixel format");
+      }
+
+      AttachTexture(stencilTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.stencilLevel);
+    }
+    else if(mCreateInfo.depthStencilAttachment.depthTexture)
+    {
+      // bind depth texture.
       auto depthTexture = static_cast<const GLES::Texture*>(mCreateInfo.depthStencilAttachment.depthTexture);
       auto attachmentId = DEPTH_STENCIL_ATTACHMENT_TYPE(depthTexture->GetCreateInfo().format).attachment;
 
+      if(attachmentId != GL_DEPTH_STENCIL_ATTACHMENT && mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
+      {
+        DALI_LOG_ERROR("Current Depth Texture Type doesn't support to store Stencil. Please check depth texture's pixel format");
+      }
+
       AttachTexture(depthTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.depthLevel);
     }
+    else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE &&
+            mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
+    {
+      // Create depth+stencil renderbuffer
+      gl->GenRenderbuffers(1, &mStencilBufferId);
+      gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
+      gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mCreateInfo.size.width, mCreateInfo.size.height);
+      gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferId);
+    }
     else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
     {
+      // Create depth renderbuffer
       gl->GenRenderbuffers(1, &mDepthBufferId);
       gl->BindRenderbuffer(GL_RENDERBUFFER, mDepthBufferId);
       gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mCreateInfo.size.width, mCreateInfo.size.height);
       gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBufferId);
     }
-
-    if(mCreateInfo.depthStencilAttachment.stencilTexture)
-    {
-      auto stencilTexture = static_cast<const GLES::Texture*>(mCreateInfo.depthStencilAttachment.stencilTexture);
-      auto attachmentId   = DEPTH_STENCIL_ATTACHMENT_TYPE(stencilTexture->GetCreateInfo().format).attachment;
-
-      AttachTexture(stencilTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.stencilLevel);
-    }
     else if(mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
     {
+      // Create stencil renderbuffer
       gl->GenRenderbuffers(1, &mStencilBufferId);
       gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
       gl->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mCreateInfo.size.width, mCreateInfo.size.height);