intel: Add render target attachments at BeginCommandBuffer for TilerGpus

Still allow for binding via CmdBindAttachments as the default if no
RENDER_PASS object is specified at begin time.  This allows for easier testing.
diff --git a/icd/intel/cmd.c b/icd/intel/cmd.c
index 67119d5..ef11bc6 100644
--- a/icd/intel/cmd.c
+++ b/icd/intel/cmd.c
@@ -32,6 +32,7 @@
 #include "mem.h"
 #include "obj.h"
 #include "cmd_priv.h"
+#include "fb.h"
 
 /**
  * Free all resources used by a writer.  Note that the initial size is not
@@ -232,6 +233,8 @@
     if (cmd->bind.shader_cache.entries)
         icd_free(cmd->bind.shader_cache.entries);
 
+    icd_free(cmd->bind.render_pass);  // TODO remove once CmdBindAttachment is removed
+
     memset(&cmd->bind, 0, sizeof(cmd->bind));
 
     cmd->reloc_used = 0;
@@ -304,13 +307,37 @@
     intel_base_destroy(&cmd->obj.base);
 }
 
-XGL_RESULT intel_cmd_begin(struct intel_cmd *cmd, XGL_FLAGS flags)
+XGL_RESULT intel_cmd_begin(struct intel_cmd *cmd, const XGL_CMD_BUFFER_BEGIN_INFO* info)
 {
     XGL_RESULT ret;
     XGL_UINT i;
+    XGL_FLAGS flags = 0;
+    XGL_CMD_BUFFER_BEGIN_INFO* next= (XGL_CMD_BUFFER_BEGIN_INFO*) info;
+    XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO *ginfo;
 
     cmd_reset(cmd);
 
+    while (next != NULL) {
+        switch (next->sType) {
+        case XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO:
+            flags = next->flags;
+            break;
+        case XGL_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO:
+            ginfo = (XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO *) next;
+            cmd->bind.render_pass = (struct intel_render_pass *)
+                                        ginfo->renderPass;
+            break;
+        default:
+            return XGL_ERROR_INVALID_VALUE;
+            break;
+        }
+        next = (XGL_CMD_BUFFER_BEGIN_INFO*) next->pNext;
+    }
+
+    if (cmd->bind.render_pass == NULL)  //  TODO remove once CmmdBindAttachment is removed
+        cmd->bind.render_pass = icd_alloc(sizeof(struct intel_render_pass), 0,
+                                  XGL_SYSTEM_ALLOC_INTERNAL);
+
     if (cmd->flags != flags) {
         cmd->flags = flags;
         cmd->writers[INTEL_CMD_WRITER_BATCH].size = 0;
@@ -429,11 +456,11 @@
 
 ICD_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(
     XGL_CMD_BUFFER                              cmdBuffer,
-    XGL_FLAGS                                   flags)
+    const XGL_CMD_BUFFER_BEGIN_INFO            *info)
 {
     struct intel_cmd *cmd = intel_cmd(cmdBuffer);
 
-    return intel_cmd_begin(cmd, flags);
+    return intel_cmd_begin(cmd, info);
 }
 
 ICD_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(
diff --git a/icd/intel/cmd.h b/icd/intel/cmd.h
index bf921e4..10a5353 100644
--- a/icd/intel/cmd.h
+++ b/icd/intel/cmd.h
@@ -192,14 +192,7 @@
         XGL_INDEX_TYPE type;
     } index;
 
-    struct {
-        const struct intel_rt_view *rt[XGL_MAX_COLOR_ATTACHMENTS];
-        XGL_UINT rt_count;
-
-        const struct intel_ds_view *ds;
-
-        XGL_UINT width, height;
-    } att;
+    struct intel_render_pass *render_pass;
 
     XGL_UINT draw_count;
     uint32_t wa_flags;
@@ -253,7 +246,7 @@
                             struct intel_cmd **cmd_ret);
 void intel_cmd_destroy(struct intel_cmd *cmd);
 
-XGL_RESULT intel_cmd_begin(struct intel_cmd *cmd, XGL_FLAGS flags);
+XGL_RESULT intel_cmd_begin(struct intel_cmd *cmd, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo);
 XGL_RESULT intel_cmd_end(struct intel_cmd *cmd);
 
 void intel_cmd_decode(struct intel_cmd *cmd);
diff --git a/icd/intel/cmd_pipeline.c b/icd/intel/cmd_pipeline.c
index 4c02ebc..4d36a4d 100644
--- a/icd/intel/cmd_pipeline.c
+++ b/icd/intel/cmd_pipeline.c
@@ -36,6 +36,7 @@
 #include "state.h"
 #include "view.h"
 #include "cmd_priv.h"
+#include "fb.h"
 
 static void gen6_3DPRIMITIVE(struct intel_cmd *cmd,
                              int prim_type, bool indexed,
@@ -1586,8 +1587,8 @@
         case INTEL_PIPELINE_RMAP_SLOT_RT:
             {
                 const struct intel_rt_view *view =
-                    (slot->u.index < cmd->bind.att.rt_count) ?
-                    cmd->bind.att.rt[slot->u.index] : NULL;
+                    (slot->u.index < cmd->bind.render_pass->fb->rt_count) ?
+                    cmd->bind.render_pass->fb->rt[slot->u.index] : NULL;
 
                 if (view) {
                     offset = cmd_surface_write(cmd, INTEL_CMD_ITEM_SURFACE,
@@ -1893,13 +1894,13 @@
 static void emit_rt(struct intel_cmd *cmd)
 {
     cmd_wa_gen6_pre_depth_stall_write(cmd);
-    gen6_3DSTATE_DRAWING_RECTANGLE(cmd, cmd->bind.att.width,
-            cmd->bind.att.height);
+    gen6_3DSTATE_DRAWING_RECTANGLE(cmd, cmd->bind.render_pass->fb->width,
+            cmd->bind.render_pass->fb->height);
 }
 
 static void emit_ds(struct intel_cmd *cmd)
 {
-    const struct intel_ds_view *ds = cmd->bind.att.ds;
+    const struct intel_ds_view *ds = cmd->bind.render_pass->fb->ds;
 
     if (!ds) {
         /* all zeros */
@@ -2986,27 +2987,27 @@
                 height = layout->height0;
         }
 
-        cmd->bind.att.rt[i] = rt;
+        cmd->bind.render_pass->fb->rt[i] = rt;
     }
 
-    cmd->bind.att.rt_count = rt_count;
+    cmd->bind.render_pass->fb->rt_count = rt_count;
 
     if (ds_info) {
         const struct intel_layout *layout;
 
-        cmd->bind.att.ds = intel_ds_view(ds_info->view);
-        layout = &cmd->bind.att.ds->img->layout;
+        cmd->bind.render_pass->fb->ds = intel_ds_view(ds_info->view);
+        layout = &cmd->bind.render_pass->fb->ds->img->layout;
 
         if (width > layout->width0)
             width = layout->width0;
         if (height > layout->height0)
             height = layout->height0;
     } else {
-        cmd->bind.att.ds = NULL;
+        cmd->bind.render_pass->fb->ds = NULL;
     }
 
-    cmd->bind.att.width = width;
-    cmd->bind.att.height = height;
+    cmd->bind.render_pass->fb->width = width;
+    cmd->bind.render_pass->fb->height = height;
 }
 
 static void cmd_bind_viewport_state(struct intel_cmd *cmd,
diff --git a/icd/intel/fb.c b/icd/intel/fb.c
index 174e47c..fe5def1 100644
--- a/icd/intel/fb.c
+++ b/icd/intel/fb.c
@@ -24,9 +24,19 @@
  */
 
 #include "dev.h"
+#include "mem.h"
 #include "obj.h"
+#include "view.h"
+#include "img.h"
 #include "fb.h"
 
+static void fb_destroy(struct intel_obj *obj)
+{
+    struct intel_framebuffer *fb = intel_fb_from_obj(obj);
+
+    intel_fb_destroy(fb);
+}
+
 XGL_RESULT intel_fb_create(struct intel_dev *dev,
                            const XGL_FRAMEBUFFER_CREATE_INFO* info,
                            struct intel_framebuffer ** fb_ret)
@@ -36,7 +46,47 @@
             dev->base.dbg, XGL_DBG_OBJECT_FRAMEBUFFER, info, 0);
     if (!fb)
         return XGL_ERROR_OUT_OF_MEMORY;
-    //todo
+
+    XGL_UINT width = 0, height = 0;
+    XGL_UINT i;
+
+    for (i = 0; i < info->colorAttachmentCount; i++) {
+        const XGL_COLOR_ATTACHMENT_BIND_INFO *att = &(info->pColorAttachments[i]);
+        const struct intel_rt_view *rt = intel_rt_view(att->view);
+        const struct intel_layout *layout = &rt->img->layout;
+
+        if (i == 0) {
+            width = layout->width0;
+            height = layout->height0;
+        } else {
+            if (width > layout->width0)
+                width = layout->width0;
+            if (height > layout->height0)
+                height = layout->height0;
+        }
+
+        fb->rt[i] = rt;
+    }
+    fb->rt_count = info->colorAttachmentCount;
+
+    if (info->pDepthStencilAttachment) {
+        const struct intel_layout *layout;
+
+        fb->ds = intel_ds_view(info->pDepthStencilAttachment->view);
+        layout = &fb->ds->img->layout;
+
+        if (width > layout->width0)
+            width = layout->width0;
+        if (height > layout->height0)
+            height = layout->height0;
+    } else {
+        fb->ds = NULL;
+    }
+
+    fb->sample_count = info->sampleCount;
+    fb->width = width;
+    fb->height = height;
+    fb->obj.destroy = fb_destroy;
 
     *fb_ret = fb;
 
@@ -44,7 +94,19 @@
 
 }
 
-XGL_RESULT intel_rp_create(struct intel_dev *dev,
+void intel_fb_destroy(struct intel_framebuffer *fb)
+{
+    intel_base_destroy(&fb->obj.base);
+}
+
+static void render_pass_destroy(struct intel_obj *obj)
+{
+    struct intel_render_pass *rp = intel_rp_from_obj(obj);
+
+    intel_rp_destroy(rp);
+}
+
+XGL_RESULT intel_render_pass_create(struct intel_dev *dev,
                            const XGL_RENDER_PASS_CREATE_INFO* info,
                            struct intel_render_pass** rp_ret)
 {
@@ -53,13 +115,23 @@
             dev->base.dbg, XGL_DBG_OBJECT_RENDER_PASS, info, 0);
     if (!rp)
         return XGL_ERROR_OUT_OF_MEMORY;
-    //todo
+
+    rp->obj.destroy = render_pass_destroy;
+    rp->fb = intel_framebuffer(info->framebuffer);
+    //TODO add any clear color ops
 
     *rp_ret = rp;
 
     return XGL_SUCCESS;
 }
 
+void intel_render_pass_destroy(struct intel_render_pass *rp)
+{
+    rp->fb = NULL;
+
+    intel_base_destroy(&rp->obj.base);
+}
+
 XGL_RESULT XGLAPI intelCreateFramebuffer(
     XGL_DEVICE                                  device,
     const XGL_FRAMEBUFFER_CREATE_INFO*          info,
@@ -78,7 +150,7 @@
 {
     struct intel_dev *dev = intel_dev(device);
 
-    return intel_rp_create(dev, info, (struct intel_render_pass **) rp_ret);
+    return intel_render_pass_create(dev, info, (struct intel_render_pass **) rp_ret);
 }
 
 
diff --git a/icd/intel/fb.h b/icd/intel/fb.h
index 6b05097..e89ccd6 100644
--- a/icd/intel/fb.h
+++ b/icd/intel/fb.h
@@ -25,15 +25,53 @@
 #pragma once
 
 struct intel_framebuffer {
-    struct intel_base base;
+    struct intel_obj obj;
 
+    const struct intel_rt_view *rt[XGL_MAX_COLOR_ATTACHMENTS];
+    XGL_UINT rt_count;
+
+    const struct intel_ds_view *ds;
+
+    XGL_UINT sample_count;
+    XGL_UINT width, height;
 };
 
 struct intel_render_pass {
-    struct intel_base base;
+    struct intel_obj obj;
 
+    struct intel_framebuffer *fb;
 };
 
+static inline struct intel_framebuffer *intel_framebuffer(XGL_FRAMEBUFFER fb)
+{
+    return (struct intel_framebuffer *) fb;
+}
+
+static inline struct intel_framebuffer *intel_fb_from_obj(struct intel_obj *obj)
+{
+    return (struct intel_framebuffer *) obj;
+}
+
+static inline struct intel_render_pass *intel_render_pass(XGL_RENDER_PASS rp)
+{
+    return (struct intel_render_pass *) rp;
+}
+
+static inline struct intel_render_pass *intel_rp_from_obj(struct intel_obj *obj)
+{
+    return (struct intel_render_pass *) obj;
+}
+
+XGL_RESULT intel_fb_create(struct intel_dev *dev,
+                           const XGL_FRAMEBUFFER_CREATE_INFO* pInfo,
+                           struct intel_framebuffer ** ppFramebuffer);
+void intel_fb_destroy(struct intel_framebuffer *fb);
+
+XGL_RESULT intel_rp_create(struct intel_dev *dev,
+                           const XGL_RENDER_PASS_CREATE_INFO* pInfo,
+                           struct intel_render_pass** ppRenderPass);
+void intel_rp_destroy(struct intel_render_pass *rp);
+
 XGL_RESULT XGLAPI intelCreateFramebuffer(
     XGL_DEVICE                                  device,
     const XGL_FRAMEBUFFER_CREATE_INFO*          pCreateInfo,