The fact that there can be duplicate entries per (dname, ename, role) is indication for an over-simplified test case. I suspect the test case should really be:
CREATE TEMP TABLE emp(dname text, ename text, role text, col1 text);
INSERT INTO emp VALUES
    ('D1','E11', 'Role1', 'foo1')
   ,('D1','E11', 'Role2', 'foo2')
   ,('D1','E12', 'Role1', 'foo3')
   ,('D1','E12', 'Role1', 'foo4')
   ,('D2','E12', 'Role2', 'foo5');
Then @Clodoaldo's (otherwise fine) query would have to use:
SELECT DISTINCT dname, ename, role
instead of:
SELECT DISTINCT *
An alternative would be a crosstab query:
SELECT * FROM crosstab(
      $x$
      SELECT dname, role, count(DISTINCT ename)::int
      FROM   emp
      GROUP  BY dname, role
      $x$
      ,$y$SELECT DISTINCT role FROM emp ORDER BY 1$y$)
AS ct (dname text, "Role1" text, "Role2" int);
You need the tablefunc installed for this. More details for this query in this related answer:
PostgreSQL Crosstab Query
You have to list all possible roles in the column definition list.