00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "pipe/p_state.h"
00036 #include "pipe/p_shader_tokens.h"
00037 #include "spu_exec.h"
00038 #include "spu_vertex_shader.h"
00039 #include "spu_main.h"
00040 #include "spu_dcache.h"
00041
00042 typedef void (*spu_fetch_func)(qword *out, const qword *in,
00043 const qword *shuffle_data);
00044
00045
00046 static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = {
00047
00048
00049 {
00050 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
00051 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
00052 },
00053
00054
00055
00056 {
00057 0x00, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80,
00058 0x02, 0x80, 0x80, 0x80, 0x03, 0x80, 0x80, 0x80,
00059 },
00060
00061
00062
00063 {
00064 0x00, 0x01, 0x80, 0x80, 0x02, 0x03, 0x80, 0x80,
00065 0x04, 0x05, 0x80, 0x80, 0x06, 0x07, 0x80, 0x80,
00066 },
00067
00068
00069
00070 {
00071 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
00072 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17
00073 },
00074
00075
00076
00077 {
00078 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
00079 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F
00080 }
00081 };
00082
00083
00087 static void generic_vertex_fetch(struct spu_vs_context *draw,
00088 struct spu_exec_machine *machine,
00089 const unsigned *elts,
00090 unsigned count)
00091 {
00092 unsigned nr_attrs = draw->vertex_fetch.nr_attrs;
00093 unsigned attr;
00094
00095 ASSERT(count <= 4);
00096
00097 #if DRAW_DBG
00098 printf("SPU: %s count = %u, nr_attrs = %u\n",
00099 __FUNCTION__, count, nr_attrs);
00100 #endif
00101
00102
00103
00104 for (attr = 0; attr < nr_attrs; attr++) {
00105 const unsigned pitch = draw->vertex_fetch.pitch[attr];
00106 const uint64_t src = draw->vertex_fetch.src_ptr[attr];
00107 const spu_fetch_func fetch = (spu_fetch_func)
00108 (draw->vertex_fetch.code + draw->vertex_fetch.code_offset[attr]);
00109 unsigned i;
00110 unsigned idx;
00111 const unsigned bytes_per_entry = draw->vertex_fetch.size[attr];
00112 const unsigned quads_per_entry = (bytes_per_entry + 15) / 16;
00113 qword in[2 * 4] ALIGN16_ATTRIB;
00114
00115
00116
00117
00118 idx = 0;
00119 for (i = 0; i < count; i++) {
00120 const uint64_t addr = src + (elts[i] * pitch);
00121
00122 #if DRAW_DBG
00123 printf("SPU: fetching = 0x%llx\n", addr);
00124 #endif
00125
00126 spu_dcache_fetch_unaligned(& in[idx], addr, bytes_per_entry);
00127 idx += quads_per_entry;
00128 }
00129
00130
00131
00132 (void) memset(& in[idx], 0, (8 - idx) * sizeof(qword));
00133
00134
00135
00136
00137 (*fetch)(&machine->Inputs[attr].xyzw[0].q, in, fetch_shuffle_data);
00138 }
00139 }
00140
00141
00142 void spu_update_vertex_fetch( struct spu_vs_context *draw )
00143 {
00144 draw->vertex_fetch.fetch_func = generic_vertex_fetch;
00145 }