/** * Emit all the constants in a constant buffer for a shader stage. */ static enum pipe_error emit_consts(struct svga_context *svga, unsigned shader) { struct svga_screen *ss = svga_screen(svga->pipe.screen); struct pipe_transfer *transfer = NULL; unsigned count; const float (*data)[4] = NULL; unsigned i; enum pipe_error ret = PIPE_OK; const unsigned offset = 0; assert(shader < PIPE_SHADER_TYPES); if (svga->curr.cb[shader] == NULL) goto done; count = svga->curr.cb[shader]->width0 / (4 * sizeof(float)); data = (const float (*)[4])pipe_buffer_map(&svga->pipe, svga->curr.cb[shader], PIPE_TRANSFER_READ, &transfer); if (data == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto done; } if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) { ret = emit_const_range( svga, shader, offset, count, data ); if (ret != PIPE_OK) { goto done; } } else { for (i = 0; i < count; i++) { ret = emit_const( svga, shader, offset + i, data[i] ); if (ret != PIPE_OK) { goto done; } } } done: if (data) pipe_buffer_unmap(&svga->pipe, transfer); return ret; }
/** * Emit all the constants in a constant buffer for a shader stage. * On VGPU10, emit_consts_vgpu10 is used instead. */ static enum pipe_error emit_consts_vgpu9(struct svga_context *svga, unsigned shader) { const struct pipe_constant_buffer *cbuf; struct svga_screen *ss = svga_screen(svga->pipe.screen); struct pipe_transfer *transfer = NULL; unsigned count; const float (*data)[4] = NULL; unsigned i; enum pipe_error ret = PIPE_OK; const unsigned offset = 0; assert(shader < PIPE_SHADER_TYPES); assert(!svga_have_vgpu10(svga)); /* Only one constant buffer per shader is supported before VGPU10. * This is only an approximate check against that. */ assert(svga->curr.constbufs[shader][1].buffer == NULL); cbuf = &svga->curr.constbufs[shader][0]; if (svga->curr.constbufs[shader][0].buffer) { /* emit user-provided constants */ data = (const float (*)[4]) pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer, PIPE_TRANSFER_READ, &transfer); if (!data) { return PIPE_ERROR_OUT_OF_MEMORY; } /* sanity check */ assert(cbuf->buffer->width0 >= cbuf->buffer_size); /* Use/apply the constant buffer size and offsets here */ count = cbuf->buffer_size / (4 * sizeof(float)); data += cbuf->buffer_offset / (4 * sizeof(float)); if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) { ret = emit_const_range( svga, shader, offset, count, data ); } else { for (i = 0; i < count; i++) { ret = emit_const( svga, shader, offset + i, data[i] ); if (ret != PIPE_OK) { break; } } } pipe_buffer_unmap(&svga->pipe, transfer); if (ret != PIPE_OK) { return ret; } } /* emit extra shader constants */ { const struct svga_shader_variant *variant = NULL; unsigned offset; float extras[MAX_EXTRA_CONSTS][4]; unsigned count, i; switch (shader) { case PIPE_SHADER_VERTEX: variant = svga->state.hw_draw.vs; count = svga_get_extra_vs_constants(svga, (float *) extras); break; case PIPE_SHADER_FRAGMENT: variant = svga->state.hw_draw.fs; count = svga_get_extra_fs_constants(svga, (float *) extras); break; default: assert(!"Unexpected shader type"); count = 0; } assert(variant); offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1; assert(count <= ARRAY_SIZE(extras)); if (count > 0) { if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) { ret = emit_const_range(svga, shader, offset, count, (const float (*) [4])extras); } else { for (i = 0; i < count; i++) { ret = emit_const(svga, shader, offset + i, extras[i]); if (ret != PIPE_OK) return ret; } } } } return ret; }