- svga->curr.zero_stride_vertex_elements = 0;
- svga->curr.num_zero_stride_vertex_elements = 0;
-
- for (i = 0; i < svga->curr.velems->count; i++) {
- const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
- const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
- vel->vertex_buffer_index];
-
- if (vbuffer->stride == 0) {
- unsigned const_idx =
- svga->curr.num_zero_stride_vertex_elements;
- struct pipe_transfer *transfer;
- struct translate *translate;
- struct translate_key key;
- void *mapped_buffer;
-
- svga->curr.zero_stride_vertex_elements |= (1 << i);
- ++svga->curr.num_zero_stride_vertex_elements;
-
- key.output_stride = 4 * sizeof(float);
- key.nr_elements = 1;
- key.element[0].type = TRANSLATE_ELEMENT_NORMAL;
- key.element[0].input_format = vel->src_format;
- key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- key.element[0].input_buffer = vel->vertex_buffer_index;
- key.element[0].input_offset = vel->src_offset;
- key.element[0].instance_divisor = vel->instance_divisor;
- key.element[0].output_offset = const_idx * 4 * sizeof(float);
-
- translate_key_sanitize(&key);
- /* translate_generic_create is technically private but
- * we don't want to code-generate, just want generic
- * translation */
- translate = translate_generic_create(&key);
-
- assert(vel->src_offset == 0);
-
- mapped_buffer = pipe_buffer_map_range(&svga->pipe,
- vbuffer->buffer,
- vel->src_offset,
- util_format_get_blocksize(vel->src_format),
- PIPE_TRANSFER_READ,
- &transfer);
-
- translate->set_buffer(translate, vel->vertex_buffer_index,
- mapped_buffer,
- vbuffer->stride);
- translate->run(translate, 0, 1, 0,
- svga->curr.zero_stride_constants);
-
- pipe_buffer_unmap(&svga->pipe,
- vbuffer->buffer,
- transfer);
-
- translate->release(translate);
+ for (i = 0; i < num_elements; i++) {
+ ureg_MOV(ureg, dst[i], src[i]);
+ }
+
+ ureg_END(ureg);
+
+ memset(&new_vs, 0, sizeof(new_vs));
+ new_vs.base.tokens = ureg_get_tokens(ureg, NULL);
+ tgsi_scan_shader(new_vs.base.tokens, &new_vs.base.info);
+
+ memset(&key, 0, sizeof(key));
+ key.vs.undo_viewport = 1;
+
+ ret = compile_vs(svga, &new_vs, &key, &variant);
+ if (ret != PIPE_OK)
+ return ret;
+
+ ureg_free_tokens(new_vs.base.tokens);
+ ureg_destroy(ureg);
+
+ /* Overwrite the variant key to indicate it's a pass-through VS */
+ memset(&variant->key, 0, sizeof(variant->key));
+ variant->key.vs.passthrough = 1;
+ variant->key.vs.undo_viewport = 1;
+
+ *out_variant = variant;
+
+ return PIPE_OK;
+}
+
+
+static enum pipe_error
+emit_hw_vs(struct svga_context *svga, unsigned dirty)
+{
+ struct svga_shader_variant *variant;
+ struct svga_vertex_shader *vs = svga->curr.vs;
+ struct svga_fragment_shader *fs = svga->curr.fs;
+ enum pipe_error ret = PIPE_OK;
+ struct svga_compile_key key;
+
+ SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITVS);
+
+ /* If there is an active geometry shader, and it has stream output
+ * defined, then we will skip the stream output from the vertex shader
+ */
+ if (!svga_have_gs_streamout(svga)) {
+ /* No GS stream out */
+ if (svga_have_vs_streamout(svga)) {
+ /* Set VS stream out */
+ ret = svga_set_stream_output(svga, vs->base.stream_output);
+ }
+ else {
+ /* turn off stream out */
+ ret = svga_set_stream_output(svga, NULL);
+ }
+ if (ret != PIPE_OK) {
+ goto done;
+ }
+ }
+
+ /* SVGA_NEW_NEED_SWTNL */
+ if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) {
+ /* No vertex shader is needed */
+ variant = NULL;
+ }
+ else {
+ make_vs_key(svga, &key);
+
+ /* See if we already have a VS variant that matches the key */
+ variant = svga_search_shader_key(&vs->base, &key);
+
+ if (!variant) {
+ /* Create VS variant now */
+ if (key.vs.passthrough) {
+ ret = compile_passthrough_vs(svga, vs, fs, &variant);
+ }
+ else {
+ ret = compile_vs(svga, vs, &key, &variant);
+ }
+ if (ret != PIPE_OK)
+ goto done;
+
+ /* insert the new variant at head of linked list */
+ assert(variant);
+ variant->next = vs->base.variants;
+ vs->base.variants = variant;