diff options
author | Christian König <deathsimple@vodafone.de> | 2011-02-28 02:00:01 +0100 |
---|---|---|
committer | Christian König <deathsimple@vodafone.de> | 2011-02-28 02:19:39 +0100 |
commit | 96bbc627f369c0100b950f81531b1fe9ef586c34 (patch) | |
tree | 0e207f62473191afc2faa36c0284696009d754fe | |
parent | bce4f9ac395986ee0acae2702ed73448333d81b8 (diff) |
r600g: implement instanced drawing support
-rw-r--r-- | src/gallium/drivers/r600/eg_asm.c | 26 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 230 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 31 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 2 |
6 files changed, 191 insertions, 103 deletions
diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index 80c5de39750..8190df725df 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c | |||
@@ -94,31 +94,9 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) | |||
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | void eg_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count) | 97 | void eg_cf_vtx(struct r600_vertex_element *ve) |
98 | { | 98 | { |
99 | struct r600_pipe_state *rstate; | 99 | struct r600_pipe_state *rstate = &ve->rstate; |
100 | unsigned i = 0; | ||
101 | |||
102 | if (count > 8) { | ||
103 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1); | ||
104 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
105 | S_SQ_CF_WORD1_BARRIER(1) | | ||
106 | S_SQ_CF_WORD1_COUNT(8 - 1); | ||
107 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(40 >> 1); | ||
108 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
109 | S_SQ_CF_WORD1_BARRIER(1) | | ||
110 | S_SQ_CF_WORD1_COUNT(count - 8 - 1); | ||
111 | } else { | ||
112 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1); | ||
113 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
114 | S_SQ_CF_WORD1_BARRIER(1) | | ||
115 | S_SQ_CF_WORD1_COUNT(count - 1); | ||
116 | } | ||
117 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(0); | ||
118 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN) | | ||
119 | S_SQ_CF_WORD1_BARRIER(1); | ||
120 | |||
121 | rstate = &ve->rstate; | ||
122 | rstate->id = R600_PIPE_STATE_FETCH_SHADER; | 100 | rstate->id = R600_PIPE_STATE_FETCH_SHADER; |
123 | rstate->nregs = 0; | 101 | rstate->nregs = 0; |
124 | r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS, | 102 | r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS, |
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index de796188fde..5d59356bf70 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c | |||
@@ -83,6 +83,7 @@ static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r | |||
83 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: | 83 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: |
84 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: | 84 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: |
85 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: | 85 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: |
86 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT: | ||
86 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: | 87 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: |
87 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: | 88 | case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: |
88 | return 1; | 89 | return 1; |
@@ -1374,7 +1375,8 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign | |||
1374 | S_SQ_VTX_WORD1_FORMAT_COMP_ALL(vtx->format_comp_all) | | 1375 | S_SQ_VTX_WORD1_FORMAT_COMP_ALL(vtx->format_comp_all) | |
1375 | S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) | | 1376 | S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) | |
1376 | S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); | 1377 | S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); |
1377 | bc->bytecode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1); | 1378 | bc->bytecode[id++] = S_SQ_VTX_WORD2_OFFSET(vtx->offset) | |
1379 | S_SQ_VTX_WORD2_MEGA_FETCH(1); | ||
1378 | bc->bytecode[id++] = 0; | 1380 | bc->bytecode[id++] = 0; |
1379 | return 0; | 1381 | return 0; |
1380 | } | 1382 | } |
@@ -1894,12 +1896,13 @@ void r600_bc_dump(struct r600_bc *bc) | |||
1894 | fprintf(stderr, "SEL_Z:%d ", vtx->dst_sel_z); | 1896 | fprintf(stderr, "SEL_Z:%d ", vtx->dst_sel_z); |
1895 | fprintf(stderr, "SEL_W:%d) ", vtx->dst_sel_w); | 1897 | fprintf(stderr, "SEL_W:%d) ", vtx->dst_sel_w); |
1896 | fprintf(stderr, "USE_CONST_FIELDS:%d ", vtx->use_const_fields); | 1898 | fprintf(stderr, "USE_CONST_FIELDS:%d ", vtx->use_const_fields); |
1897 | fprintf(stderr, "DATA_FORMAT:%d ", vtx->data_format); | 1899 | fprintf(stderr, "FORMAT(DATA:%d ", vtx->data_format); |
1898 | fprintf(stderr, "NUM_FORMAT_ALL:%d ", vtx->num_format_all); | 1900 | fprintf(stderr, "NUM:%d ", vtx->num_format_all); |
1899 | fprintf(stderr, "FORMAT_COMP_ALL:%d ", vtx->format_comp_all); | 1901 | fprintf(stderr, "COMP:%d ", vtx->format_comp_all); |
1900 | fprintf(stderr, "SRF_MODE_ALL:%d\n", vtx->srf_mode_all); | 1902 | fprintf(stderr, "MODE:%d)\n", vtx->srf_mode_all); |
1901 | id++; | 1903 | id++; |
1902 | fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); | 1904 | fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); |
1905 | fprintf(stderr, "OFFSET:%d\n", vtx->offset); | ||
1903 | //TODO | 1906 | //TODO |
1904 | id++; | 1907 | id++; |
1905 | fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); | 1908 | fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); |
@@ -1910,29 +1913,9 @@ void r600_bc_dump(struct r600_bc *bc) | |||
1910 | fprintf(stderr, "--------------------------------------\n"); | 1913 | fprintf(stderr, "--------------------------------------\n"); |
1911 | } | 1914 | } |
1912 | 1915 | ||
1913 | static void r600_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count) | 1916 | static void r600_cf_vtx(struct r600_vertex_element *ve) |
1914 | { | 1917 | { |
1915 | struct r600_pipe_state *rstate; | 1918 | struct r600_pipe_state *rstate; |
1916 | unsigned i = 0; | ||
1917 | |||
1918 | if (count > 8) { | ||
1919 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1); | ||
1920 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
1921 | S_SQ_CF_WORD1_BARRIER(1) | | ||
1922 | S_SQ_CF_WORD1_COUNT(8 - 1); | ||
1923 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(40 >> 1); | ||
1924 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
1925 | S_SQ_CF_WORD1_BARRIER(1) | | ||
1926 | S_SQ_CF_WORD1_COUNT(count - 8 - 1); | ||
1927 | } else { | ||
1928 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(8 >> 1); | ||
1929 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) | | ||
1930 | S_SQ_CF_WORD1_BARRIER(1) | | ||
1931 | S_SQ_CF_WORD1_COUNT(count - 1); | ||
1932 | } | ||
1933 | bytecode[i++] = S_SQ_CF_WORD0_ADDR(0); | ||
1934 | bytecode[i++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_RETURN) | | ||
1935 | S_SQ_CF_WORD1_BARRIER(1); | ||
1936 | 1919 | ||
1937 | rstate = &ve->rstate; | 1920 | rstate = &ve->rstate; |
1938 | rstate->id = R600_PIPE_STATE_FETCH_SHADER; | 1921 | rstate->id = R600_PIPE_STATE_FETCH_SHADER; |
@@ -2078,37 +2061,19 @@ out_unknown: | |||
2078 | 2061 | ||
2079 | int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve) | 2062 | int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve) |
2080 | { | 2063 | { |
2081 | unsigned ndw, i; | 2064 | static int dump_shaders = -1; |
2082 | u32 *bytecode; | 2065 | |
2083 | unsigned fetch_resource_start = 0, format, num_format, format_comp; | 2066 | struct r600_bc bc; |
2067 | struct r600_bc_vtx vtx; | ||
2084 | struct pipe_vertex_element *elements = ve->elements; | 2068 | struct pipe_vertex_element *elements = ve->elements; |
2085 | const struct util_format_description *desc; | 2069 | const struct util_format_description *desc; |
2086 | 2070 | unsigned fetch_resource_start = rctx->family >= CHIP_CEDAR ? 0 : 160; | |
2087 | /* 2 dwords for cf aligned to 4 + 4 dwords per input */ | 2071 | unsigned format, num_format, format_comp; |
2088 | ndw = 8 + ve->count * 4; | 2072 | u32 *bytecode; |
2089 | ve->fs_size = ndw * 4; | 2073 | int i, r; |
2090 | |||
2091 | /* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */ | ||
2092 | ve->fetch_shader = r600_bo(rctx->radeon, ndw*4, 256, PIPE_BIND_VERTEX_BUFFER, 0); | ||
2093 | if (ve->fetch_shader == NULL) { | ||
2094 | return -ENOMEM; | ||
2095 | } | ||
2096 | |||
2097 | bytecode = r600_bo_map(rctx->radeon, ve->fetch_shader, 0, NULL); | ||
2098 | if (bytecode == NULL) { | ||
2099 | r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL); | ||
2100 | return -ENOMEM; | ||
2101 | } | ||
2102 | |||
2103 | if (rctx->family >= CHIP_CEDAR) { | ||
2104 | eg_cf_vtx(ve, &bytecode[0], (ndw - 8) / 4); | ||
2105 | } else { | ||
2106 | r600_cf_vtx(ve, &bytecode[0], (ndw - 8) / 4); | ||
2107 | fetch_resource_start = 160; | ||
2108 | } | ||
2109 | 2074 | ||
2110 | /* vertex elements offset need special handling, if offset is bigger | 2075 | /* vertex elements offset need special handling, if offset is bigger |
2111 | * than what we can put in fetch instruction then we need to alterate | 2076 | + * than what we can put in fetch instruction then we need to alterate |
2112 | * the vertex resource offset. In such case in order to simplify code | 2077 | * the vertex resource offset. In such case in order to simplify code |
2113 | * we will bound one resource per elements. It's a worst case scenario. | 2078 | * we will bound one resource per elements. It's a worst case scenario. |
2114 | */ | 2079 | */ |
@@ -2119,40 +2084,155 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru | |||
2119 | } | 2084 | } |
2120 | } | 2085 | } |
2121 | 2086 | ||
2087 | memset(&bc, 0, sizeof(bc)); | ||
2088 | r = r600_bc_init(&bc, r600_get_family(rctx->radeon)); | ||
2089 | if (r) | ||
2090 | return r; | ||
2091 | |||
2092 | for (i = 0; i < ve->count; i++) { | ||
2093 | if (elements[i].instance_divisor > 1) { | ||
2094 | struct r600_bc_alu alu; | ||
2095 | |||
2096 | memset(&alu, 0, sizeof(alu)); | ||
2097 | alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT); | ||
2098 | alu.src[0].sel = 0; | ||
2099 | alu.src[0].chan = 3; | ||
2100 | |||
2101 | alu.dst.sel = i + 1; | ||
2102 | alu.dst.chan = 3; | ||
2103 | alu.dst.write = 1; | ||
2104 | alu.last = 1; | ||
2105 | |||
2106 | if ((r = r600_bc_add_alu(&bc, &alu))) { | ||
2107 | r600_bc_clear(&bc); | ||
2108 | return r; | ||
2109 | } | ||
2110 | |||
2111 | memset(&alu, 0, sizeof(alu)); | ||
2112 | alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL); | ||
2113 | alu.src[0].sel = i + 1; | ||
2114 | alu.src[0].chan = 3; | ||
2115 | |||
2116 | alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; | ||
2117 | alu.src[1].value = fui(1.0f / (float)elements[i].instance_divisor); | ||
2118 | |||
2119 | alu.dst.sel = i + 1; | ||
2120 | alu.dst.chan = 3; | ||
2121 | alu.dst.write = 1; | ||
2122 | alu.last = 1; | ||
2123 | |||
2124 | if ((r = r600_bc_add_alu(&bc, &alu))) { | ||
2125 | r600_bc_clear(&bc); | ||
2126 | return r; | ||
2127 | } | ||
2128 | |||
2129 | memset(&alu, 0, sizeof(alu)); | ||
2130 | alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC); | ||
2131 | alu.src[0].sel = i + 1; | ||
2132 | alu.src[0].chan = 3; | ||
2133 | |||
2134 | alu.dst.sel = i + 1; | ||
2135 | alu.dst.chan = 3; | ||
2136 | alu.dst.write = 1; | ||
2137 | alu.last = 1; | ||
2138 | |||
2139 | if ((r = r600_bc_add_alu(&bc, &alu))) { | ||
2140 | r600_bc_clear(&bc); | ||
2141 | return r; | ||
2142 | } | ||
2143 | |||
2144 | memset(&alu, 0, sizeof(alu)); | ||
2145 | alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT); | ||
2146 | alu.src[0].sel = i + 1; | ||
2147 | alu.src[0].chan = 3; | ||
2148 | |||
2149 | alu.dst.sel = i + 1; | ||
2150 | alu.dst.chan = 3; | ||
2151 | alu.dst.write = 1; | ||
2152 | alu.last = 1; | ||
2153 | |||
2154 | if ((r = r600_bc_add_alu(&bc, &alu))) { | ||
2155 | r600_bc_clear(&bc); | ||
2156 | return r; | ||
2157 | } | ||
2158 | } | ||
2159 | } | ||
2160 | |||
2122 | for (i = 0; i < ve->count; i++) { | 2161 | for (i = 0; i < ve->count; i++) { |
2123 | unsigned vbuffer_index; | 2162 | unsigned vbuffer_index; |
2124 | r600_vertex_data_type(ve->elements[i].src_format, &format, &num_format, &format_comp); | 2163 | r600_vertex_data_type(ve->elements[i].src_format, &format, &num_format, &format_comp); |
2125 | desc = util_format_description(ve->elements[i].src_format); | 2164 | desc = util_format_description(ve->elements[i].src_format); |
2126 | if (desc == NULL) { | 2165 | if (desc == NULL) { |
2166 | r600_bc_clear(&bc); | ||
2127 | R600_ERR("unknown format %d\n", ve->elements[i].src_format); | 2167 | R600_ERR("unknown format %d\n", ve->elements[i].src_format); |
2128 | r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL); | ||
2129 | return -EINVAL; | 2168 | return -EINVAL; |
2130 | } | 2169 | } |
2131 | 2170 | ||
2132 | /* see above for vbuffer_need_offset explanation */ | 2171 | /* see above for vbuffer_need_offset explanation */ |
2133 | vbuffer_index = elements[i].vertex_buffer_index; | 2172 | vbuffer_index = elements[i].vertex_buffer_index; |
2134 | if (ve->vbuffer_need_offset) { | 2173 | memset(&vtx, 0, sizeof(vtx)); |
2135 | bytecode[8 + i * 4 + 0] = S_SQ_VTX_WORD0_BUFFER_ID(i + fetch_resource_start); | 2174 | vtx.buffer_id = (ve->vbuffer_need_offset ? i : vbuffer_index) + fetch_resource_start; |
2136 | } else { | 2175 | vtx.fetch_type = elements[i].instance_divisor ? 1 : 0; |
2137 | bytecode[8 + i * 4 + 0] = S_SQ_VTX_WORD0_BUFFER_ID(vbuffer_index + fetch_resource_start); | 2176 | vtx.src_gpr = elements[i].instance_divisor > 1 ? i + 1 : 0; |
2177 | vtx.src_sel_x = elements[i].instance_divisor ? 3 : 0; | ||
2178 | vtx.mega_fetch_count = 16; | ||
2179 | vtx.dst_gpr = i + 1; | ||
2180 | vtx.dst_sel_x = desc->swizzle[0]; | ||
2181 | vtx.dst_sel_y = desc->swizzle[1]; | ||
2182 | vtx.dst_sel_z = desc->swizzle[2]; | ||
2183 | vtx.dst_sel_w = desc->swizzle[3]; | ||
2184 | vtx.data_format = format; | ||
2185 | vtx.num_format_all = num_format; | ||
2186 | vtx.format_comp_all = format_comp; | ||
2187 | vtx.srf_mode_all = 1; | ||
2188 | vtx.offset = elements[i].src_offset; | ||
2189 | |||
2190 | if ((r = r600_bc_add_vtx(&bc, &vtx))) { | ||
2191 | r600_bc_clear(&bc); | ||
2192 | return r; | ||
2138 | } | 2193 | } |
2139 | bytecode[8 + i * 4 + 0] |= S_SQ_VTX_WORD0_SRC_GPR(0) | | ||
2140 | S_SQ_VTX_WORD0_SRC_SEL_X(0) | | ||
2141 | S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F); | ||
2142 | bytecode[8 + i * 4 + 1] = S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]) | | ||
2143 | S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]) | | ||
2144 | S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]) | | ||
2145 | S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]) | | ||
2146 | S_SQ_VTX_WORD1_USE_CONST_FIELDS(0) | | ||
2147 | S_SQ_VTX_WORD1_DATA_FORMAT(format) | | ||
2148 | S_SQ_VTX_WORD1_NUM_FORMAT_ALL(num_format) | | ||
2149 | S_SQ_VTX_WORD1_FORMAT_COMP_ALL(format_comp) | | ||
2150 | S_SQ_VTX_WORD1_SRF_MODE_ALL(1) | | ||
2151 | S_SQ_VTX_WORD1_GPR_DST_GPR(i + 1); | ||
2152 | bytecode[8 + i * 4 + 2] = S_SQ_VTX_WORD2_OFFSET(elements[i].src_offset) | | ||
2153 | S_SQ_VTX_WORD2_MEGA_FETCH(1); | ||
2154 | bytecode[8 + i * 4 + 3] = 0; | ||
2155 | } | 2194 | } |
2195 | |||
2196 | r600_bc_add_cfinst(&bc, BC_INST(&bc, V_SQ_CF_WORD1_SQ_CF_INST_RETURN)); | ||
2197 | |||
2198 | /* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */ | ||
2199 | ve->fetch_shader = r600_bo(rctx->radeon, bc.ndw*4, 256, PIPE_BIND_VERTEX_BUFFER, 0); | ||
2200 | if (ve->fetch_shader == NULL) { | ||
2201 | r600_bc_clear(&bc); | ||
2202 | return -ENOMEM; | ||
2203 | } | ||
2204 | |||
2205 | ve->fs_size = bc.ndw*4; | ||
2206 | if ((r = r600_bc_build(&bc))) { | ||
2207 | r600_bc_clear(&bc); | ||
2208 | return r; | ||
2209 | } | ||
2210 | |||
2211 | if (dump_shaders == -1) | ||
2212 | dump_shaders = debug_get_bool_option("R600_DUMP_SHADERS", FALSE); | ||
2213 | |||
2214 | if (dump_shaders) { | ||
2215 | fprintf(stderr, "--------------------------------------------------------------\n"); | ||
2216 | r600_bc_dump(&bc); | ||
2217 | fprintf(stderr, "______________________________________________________________\n"); | ||
2218 | } | ||
2219 | |||
2220 | bytecode = r600_bo_map(rctx->radeon, ve->fetch_shader, 0, NULL); | ||
2221 | if (bytecode == NULL) { | ||
2222 | r600_bc_clear(&bc); | ||
2223 | r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL); | ||
2224 | return -ENOMEM; | ||
2225 | } | ||
2226 | |||
2227 | memcpy(bytecode, bc.bytecode, ve->fs_size); | ||
2228 | |||
2156 | r600_bo_unmap(rctx->radeon, ve->fetch_shader); | 2229 | r600_bo_unmap(rctx->radeon, ve->fetch_shader); |
2230 | r600_bc_clear(&bc); | ||
2231 | |||
2232 | if (rctx->family >= CHIP_CEDAR) | ||
2233 | eg_cf_vtx(ve); | ||
2234 | else | ||
2235 | r600_cf_vtx(ve); | ||
2236 | |||
2157 | return 0; | 2237 | return 0; |
2158 | } | 2238 | } |
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index 921d0d98454..b22c21d1e23 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h | |||
@@ -103,6 +103,7 @@ struct r600_bc_vtx { | |||
103 | unsigned num_format_all; | 103 | unsigned num_format_all; |
104 | unsigned format_comp_all; | 104 | unsigned format_comp_all; |
105 | unsigned srf_mode_all; | 105 | unsigned srf_mode_all; |
106 | unsigned offset; | ||
106 | }; | 107 | }; |
107 | 108 | ||
108 | struct r600_bc_output { | 109 | struct r600_bc_output { |
@@ -189,7 +190,7 @@ struct r600_bc { | |||
189 | 190 | ||
190 | /* eg_asm.c */ | 191 | /* eg_asm.c */ |
191 | int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf); | 192 | int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf); |
192 | void eg_cf_vtx(struct r600_vertex_element *ve, u32 *bytecode, unsigned count); | 193 | void eg_cf_vtx(struct r600_vertex_element *ve); |
193 | 194 | ||
194 | /* r600_asm.c */ | 195 | /* r600_asm.c */ |
195 | int r600_bc_init(struct r600_bc *bc, enum radeon_family family); | 196 | int r600_bc_init(struct r600_bc *bc, enum radeon_family family); |
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 62d108f3518..adcd74aec76 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c | |||
@@ -285,13 +285,13 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) | |||
285 | case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: | 285 | case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: |
286 | case PIPE_CAP_DEPTH_CLAMP: | 286 | case PIPE_CAP_DEPTH_CLAMP: |
287 | case PIPE_CAP_SHADER_STENCIL_EXPORT: | 287 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
288 | case PIPE_CAP_INSTANCED_DRAWING: | ||
288 | return 1; | 289 | return 1; |
289 | 290 | ||
290 | /* Unsupported features (boolean caps). */ | 291 | /* Unsupported features (boolean caps). */ |
291 | case PIPE_CAP_STREAM_OUTPUT: | 292 | case PIPE_CAP_STREAM_OUTPUT: |
292 | case PIPE_CAP_PRIMITIVE_RESTART: | 293 | case PIPE_CAP_PRIMITIVE_RESTART: |
293 | case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ | 294 | case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ |
294 | case PIPE_CAP_INSTANCED_DRAWING: | ||
295 | return 0; | 295 | return 0; |
296 | 296 | ||
297 | case PIPE_CAP_ARRAY_TEXTURES: | 297 | case PIPE_CAP_ARRAY_TEXTURES: |
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 9fcb1d75f09..65923fb9648 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c | |||
@@ -420,6 +420,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) | |||
420 | { | 420 | { |
421 | struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration; | 421 | struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration; |
422 | unsigned i; | 422 | unsigned i; |
423 | int r; | ||
423 | 424 | ||
424 | switch (d->Declaration.File) { | 425 | switch (d->Declaration.File) { |
425 | case TGSI_FILE_INPUT: | 426 | case TGSI_FILE_INPUT: |
@@ -451,6 +452,26 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) | |||
451 | case TGSI_FILE_SAMPLER: | 452 | case TGSI_FILE_SAMPLER: |
452 | case TGSI_FILE_ADDRESS: | 453 | case TGSI_FILE_ADDRESS: |
453 | break; | 454 | break; |
455 | |||
456 | case TGSI_FILE_SYSTEM_VALUE: | ||
457 | if (d->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) { | ||
458 | struct r600_bc_alu alu; | ||
459 | memset(&alu, 0, sizeof(struct r600_bc_alu)); | ||
460 | |||
461 | alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT); | ||
462 | alu.src[0].sel = 0; | ||
463 | alu.src[0].chan = 3; | ||
464 | |||
465 | alu.dst.sel = 0; | ||
466 | alu.dst.chan = 3; | ||
467 | alu.dst.write = 1; | ||
468 | alu.last = 1; | ||
469 | |||
470 | if ((r = r600_bc_add_alu(ctx->bc, &alu))) | ||
471 | return r; | ||
472 | break; | ||
473 | } | ||
474 | |||
454 | default: | 475 | default: |
455 | R600_ERR("unsupported file %d declaration\n", d->Declaration.File); | 476 | R600_ERR("unsupported file %d declaration\n", d->Declaration.File); |
456 | return -EINVAL; | 477 | return -EINVAL; |
@@ -521,6 +542,7 @@ static void tgsi_src(struct r600_shader_ctx *ctx, | |||
521 | r600_src->swizzle[3] = tgsi_src->Register.SwizzleW; | 542 | r600_src->swizzle[3] = tgsi_src->Register.SwizzleW; |
522 | r600_src->neg = tgsi_src->Register.Negate; | 543 | r600_src->neg = tgsi_src->Register.Negate; |
523 | r600_src->abs = tgsi_src->Register.Absolute; | 544 | r600_src->abs = tgsi_src->Register.Absolute; |
545 | |||
524 | if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { | 546 | if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { |
525 | int index; | 547 | int index; |
526 | if ((tgsi_src->Register.SwizzleX == tgsi_src->Register.SwizzleY) && | 548 | if ((tgsi_src->Register.SwizzleX == tgsi_src->Register.SwizzleY) && |
@@ -535,7 +557,14 @@ static void tgsi_src(struct r600_shader_ctx *ctx, | |||
535 | index = tgsi_src->Register.Index; | 557 | index = tgsi_src->Register.Index; |
536 | r600_src->sel = V_SQ_ALU_SRC_LITERAL; | 558 | r600_src->sel = V_SQ_ALU_SRC_LITERAL; |
537 | memcpy(r600_src->value, ctx->literals + index * 4, sizeof(r600_src->value)); | 559 | memcpy(r600_src->value, ctx->literals + index * 4, sizeof(r600_src->value)); |
538 | } else { | 560 | } else if (tgsi_src->Register.File == TGSI_FILE_SYSTEM_VALUE) { |
561 | /* assume we wan't TGSI_SEMANTIC_INSTANCEID here */ | ||
562 | r600_src->swizzle[0] = 3; | ||
563 | r600_src->swizzle[1] = 3; | ||
564 | r600_src->swizzle[2] = 3; | ||
565 | r600_src->swizzle[3] = 3; | ||
566 | r600_src->sel = 0; | ||
567 | } else { | ||
539 | if (tgsi_src->Register.Indirect) | 568 | if (tgsi_src->Register.Indirect) |
540 | r600_src->rel = V_SQ_REL_RELATIVE; | 569 | r600_src->rel = V_SQ_REL_RELATIVE; |
541 | r600_src->sel = tgsi_src->Register.Index; | 570 | r600_src->sel = tgsi_src->Register.Index; |
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 72707fbd8b8..677e2209340 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c | |||
@@ -520,7 +520,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) | |||
520 | r600_context_pipe_state_set(&rctx->ctx, &vgt); | 520 | r600_context_pipe_state_set(&rctx->ctx, &vgt); |
521 | 521 | ||
522 | rdraw.vgt_num_indices = draw.info.count; | 522 | rdraw.vgt_num_indices = draw.info.count; |
523 | rdraw.vgt_num_instances = 1; | 523 | rdraw.vgt_num_instances = draw.info.instance_count; |
524 | rdraw.vgt_index_type = vgt_dma_index_type; | 524 | rdraw.vgt_index_type = vgt_dma_index_type; |
525 | rdraw.vgt_draw_initiator = vgt_draw_initiator; | 525 | rdraw.vgt_draw_initiator = vgt_draw_initiator; |
526 | rdraw.indices = NULL; | 526 | rdraw.indices = NULL; |