layers: DrawState layer can now dump png image of dot graph
diff --git a/layers/draw_state.c b/layers/draw_state.c
index 1e8b163..b16a5ef 100644
--- a/layers/draw_state.c
+++ b/layers/draw_state.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <assert.h>
 #include <pthread.h>
+#include <unistd.h>
 #include "xgl_struct_string_helper.h"
 #include "xgl_struct_graphviz_helper.h"
 #include "draw_state.h"
@@ -878,6 +879,10 @@
     if (autoDumpOnce) {
         autoDumpOnce = 0;
         dumpDotFile("pipeline_dump.dot");
+        // Convert dot to png if dot available
+        if(access( "/usr/bin/dot", X_OK) != -1) {
+            system("/usr/bin/dot pipeline_dump.dot -Tpng -o pipeline_dump.png");
+        }
     }
 }
 
@@ -2037,6 +2042,23 @@
     dumpDotFile(outFileName);
 }
 
+XGL_VOID drawStateDumpPngFile(char* outFileName)
+{
+    char dotExe[32] = "/usr/bin/dot";
+    if( access(dotExe, X_OK) != -1) {
+        dumpDotFile("/tmp/tmp.dot");
+        char dotCmd[1024];
+        sprintf(dotCmd, "%s /tmp/tmp.dot -Tpng -o %s", dotExe, outFileName);
+        system(dotCmd);
+        remove("/tmp/tmp.dot");
+    }
+    else {
+        char str[1024];
+        sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
+        layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
+    }
+}
+
 XGL_LAYER_EXPORT XGL_VOID* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* funcName)
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
@@ -2071,6 +2093,8 @@
         return xglDeviceWaitIdle;
     else if (!strncmp("drawStateDumpDotFile", (const char *) funcName, sizeof("drawStateDumpDotFile")))
         return drawStateDumpDotFile;
+    else if (!strncmp("drawStateDumpPngFile", (const char *) funcName, sizeof("drawStateDumpPngFile")))
+        return drawStateDumpPngFile;
     else if (!strncmp("xglGetMemoryHeapCount", (const char *) funcName, sizeof("xglGetMemoryHeapCount")))
         return xglGetMemoryHeapCount;
     else if (!strncmp("xglGetMemoryHeapInfo", (const char *) funcName, sizeof("xglGetMemoryHeapInfo")))
diff --git a/layers/draw_state.h b/layers/draw_state.h
index d505c46..73231e5 100644
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -44,6 +44,7 @@
     DRAWSTATE_INVALID_PIPELINE              = 16, // Invalid DS referenced
     DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS       = 17, // binding in xglCmdBindVertexData() too large for PSO's pVertexBindingDescriptions array
     DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT  = 18, // Invalid dyn state object
+    DRAWSTATE_MISSING_DOT_PROGRAM           = 19, // No "dot" program in order to generate png image
 } DRAW_STATE_ERROR;
 
 typedef enum _DRAW_TYPE
@@ -59,5 +60,7 @@
 
 //prototypes for extension functions
 XGL_VOID drawStateDumpDotFile(char* outFileName);
-// Func ptr typedef
+XGL_VOID drawStateDumpPngFile(char* outFileName);
+// Func ptr typedefs
 typedef XGL_VOID (*DRAW_STATE_DUMP_DOT_FILE)(char*);
+typedef XGL_VOID (*DRAW_STATE_DUMP_PNG_FILE)(char*);
diff --git a/tests/render_tests.cpp b/tests/render_tests.cpp
index cc96698..2d1301d 100644
--- a/tests/render_tests.cpp
+++ b/tests/render_tests.cpp
@@ -276,15 +276,17 @@
 
     GenerateClearAndPrepareBufferCmds();
     GenerateBindRenderTargetCmd();
-#ifdef DUMP_STATE_DOT
-    DRAW_STATE_DUMP_DOT_FILE pDSDumpDot = (DRAW_STATE_DUMP_DOT_FILE)xglGetProcAddr(gpu(), (XGL_CHAR*)"drawStateDumpDotFile");
-    pDSDumpDot((char*)"triTest.dot");
-#endif
+
     GenerateBindStateAndPipelineCmds();
 
     pipelineobj->BindPipelineCommandBuffer(m_cmdBuffer,descriptorSet);
     descriptorSet->BindCommandBuffer(m_cmdBuffer);
-
+#ifdef DUMP_STATE_DOT
+    DRAW_STATE_DUMP_DOT_FILE pDSDumpDot = (DRAW_STATE_DUMP_DOT_FILE)xglGetProcAddr(gpu(), (XGL_CHAR*)"drawStateDumpDotFile");
+    pDSDumpDot((char*)"triTest.dot");
+    DRAW_STATE_DUMP_PNG_FILE pDSDumpPng = (DRAW_STATE_DUMP_PNG_FILE)xglGetProcAddr(gpu(), (XGL_CHAR*)"drawStateDumpPngFile");
+    pDSDumpPng((char*)"triTest.png");
+#endif
     // render the triangle
     xglCmdDraw( m_cmdBuffer, 0, 3*numTris, 0, 1 );
 
@@ -340,13 +342,12 @@
     GenerateBindRenderTargetCmd();
     GenerateBindStateAndPipelineCmds();
 
+    pipelineobj.BindPipelineCommandBuffer(m_cmdBuffer,&descriptorSet);
+    descriptorSet.BindCommandBuffer(m_cmdBuffer);
 #ifdef DUMP_STATE_DOT
     DRAW_STATE_DUMP_DOT_FILE pDSDumpDot = (DRAW_STATE_DUMP_DOT_FILE)xglGetProcAddr(gpu(), (XGL_CHAR*)"drawStateDumpDotFile");
     pDSDumpDot((char*)"triUniFS.dot");
 #endif
-    pipelineobj.BindPipelineCommandBuffer(m_cmdBuffer,&descriptorSet);
-    descriptorSet.BindCommandBuffer(m_cmdBuffer);
-
     // render the triangle
     xglCmdDraw( m_cmdBuffer, 0, 3, 0, 1 );
 
@@ -1052,7 +1053,7 @@
     GenerateBindRenderTargetCmd();
 #ifdef DUMP_STATE_DOT
     DRAW_STATE_DUMP_DOT_FILE pDSDumpDot = (DRAW_STATE_DUMP_DOT_FILE)xglGetProcAddr(gpu(), (XGL_CHAR*)"drawStateDumpDotFile");
-    pDSDumpDot((char*)"triTest.dot");
+    pDSDumpDot((char*)"triTest2.dot");
 #endif
     GenerateBindStateAndPipelineCmds();