Rev 4358 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4358 | Rev 4401 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright 2010 Christoph Bumiller |
2 | * Copyright 2010 Christoph Bumiller |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
12 | * all copies or substantial portions of the Software. |
13 | * |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | */ |
21 | */ |
22 | 22 | ||
23 | #include "util/u_format.h" |
23 | #include "util/u_format.h" |
24 | #include "util/u_format_s3tc.h" |
24 | #include "util/u_format_s3tc.h" |
25 | #include "pipe/p_screen.h" |
25 | #include "pipe/p_screen.h" |
26 | 26 | ||
27 | #include "nv50_context.h" |
27 | #include "nv50_context.h" |
28 | #include "nv50_screen.h" |
28 | #include "nv50_screen.h" |
29 | 29 | ||
30 | #include "nouveau/nv_object.xml.h" |
30 | #include "nouveau/nv_object.xml.h" |
31 | #include |
31 | #include |
32 | 32 | ||
33 | #ifndef NOUVEAU_GETPARAM_GRAPH_UNITS |
33 | #ifndef NOUVEAU_GETPARAM_GRAPH_UNITS |
34 | # define NOUVEAU_GETPARAM_GRAPH_UNITS 13 |
34 | # define NOUVEAU_GETPARAM_GRAPH_UNITS 13 |
35 | #endif |
35 | #endif |
36 | 36 | ||
37 | /* affected by LOCAL_WARPS_LOG_ALLOC / LOCAL_WARPS_NO_CLAMP */ |
37 | /* affected by LOCAL_WARPS_LOG_ALLOC / LOCAL_WARPS_NO_CLAMP */ |
38 | #define LOCAL_WARPS_ALLOC 32 |
38 | #define LOCAL_WARPS_ALLOC 32 |
39 | /* affected by STACK_WARPS_LOG_ALLOC / STACK_WARPS_NO_CLAMP */ |
39 | /* affected by STACK_WARPS_LOG_ALLOC / STACK_WARPS_NO_CLAMP */ |
40 | #define STACK_WARPS_ALLOC 32 |
40 | #define STACK_WARPS_ALLOC 32 |
41 | 41 | ||
42 | #define THREADS_IN_WARP 32 |
42 | #define THREADS_IN_WARP 32 |
43 | 43 | ||
44 | #define ONE_TEMP_SIZE (4/*vector*/ * sizeof(float)) |
44 | #define ONE_TEMP_SIZE (4/*vector*/ * sizeof(float)) |
45 | 45 | ||
46 | static boolean |
46 | static boolean |
47 | nv50_screen_is_format_supported(struct pipe_screen *pscreen, |
47 | nv50_screen_is_format_supported(struct pipe_screen *pscreen, |
48 | enum pipe_format format, |
48 | enum pipe_format format, |
49 | enum pipe_texture_target target, |
49 | enum pipe_texture_target target, |
50 | unsigned sample_count, |
50 | unsigned sample_count, |
51 | unsigned bindings) |
51 | unsigned bindings) |
52 | { |
52 | { |
53 | if (sample_count > 8) |
53 | if (sample_count > 8) |
54 | return FALSE; |
54 | return FALSE; |
55 | if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */ |
55 | if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */ |
56 | return FALSE; |
56 | return FALSE; |
57 | if (sample_count == 8 && util_format_get_blocksizebits(format) >= 128) |
57 | if (sample_count == 8 && util_format_get_blocksizebits(format) >= 128) |
58 | return FALSE; |
58 | return FALSE; |
59 | 59 | ||
60 | if (!util_format_is_supported(format, bindings)) |
60 | if (!util_format_is_supported(format, bindings)) |
61 | return FALSE; |
61 | return FALSE; |
62 | 62 | ||
63 | switch (format) { |
63 | switch (format) { |
64 | case PIPE_FORMAT_Z16_UNORM: |
64 | case PIPE_FORMAT_Z16_UNORM: |
65 | if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS) |
65 | if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS) |
66 | return FALSE; |
66 | return FALSE; |
67 | break; |
67 | break; |
68 | default: |
68 | default: |
69 | break; |
69 | break; |
70 | } |
70 | } |
71 | 71 | ||
72 | /* transfers & shared are always supported */ |
72 | /* transfers & shared are always supported */ |
73 | bindings &= ~(PIPE_BIND_TRANSFER_READ | |
73 | bindings &= ~(PIPE_BIND_TRANSFER_READ | |
74 | PIPE_BIND_TRANSFER_WRITE | |
74 | PIPE_BIND_TRANSFER_WRITE | |
75 | PIPE_BIND_SHARED); |
75 | PIPE_BIND_SHARED); |
76 | 76 | ||
77 | return (nv50_format_table[format].usage & bindings) == bindings; |
77 | return (nv50_format_table[format].usage & bindings) == bindings; |
78 | } |
78 | } |
79 | 79 | ||
80 | static int |
80 | static int |
81 | nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) |
81 | nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) |
82 | { |
82 | { |
83 | const uint16_t class_3d = nouveau_screen(pscreen)->class_3d; |
83 | const uint16_t class_3d = nouveau_screen(pscreen)->class_3d; |
84 | 84 | ||
85 | switch (param) { |
85 | switch (param) { |
86 | case PIPE_CAP_MAX_COMBINED_SAMPLERS: |
86 | case PIPE_CAP_MAX_COMBINED_SAMPLERS: |
87 | return 64; |
87 | return 64; |
88 | case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
88 | case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
89 | return 14; |
89 | return 14; |
90 | case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
90 | case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
91 | return 12; |
91 | return 12; |
92 | case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
92 | case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
93 | return 14; |
93 | return 14; |
94 | case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
94 | case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
95 | return 512; |
95 | return 512; |
96 | case PIPE_CAP_MIN_TEXEL_OFFSET: |
96 | case PIPE_CAP_MIN_TEXEL_OFFSET: |
97 | return -8; |
97 | return -8; |
98 | case PIPE_CAP_MAX_TEXEL_OFFSET: |
98 | case PIPE_CAP_MAX_TEXEL_OFFSET: |
99 | return 7; |
99 | return 7; |
100 | case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
100 | case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
101 | case PIPE_CAP_TEXTURE_SWIZZLE: |
101 | case PIPE_CAP_TEXTURE_SWIZZLE: |
102 | case PIPE_CAP_TEXTURE_SHADOW_MAP: |
102 | case PIPE_CAP_TEXTURE_SHADOW_MAP: |
103 | case PIPE_CAP_NPOT_TEXTURES: |
103 | case PIPE_CAP_NPOT_TEXTURES: |
104 | case PIPE_CAP_ANISOTROPIC_FILTER: |
104 | case PIPE_CAP_ANISOTROPIC_FILTER: |
105 | case PIPE_CAP_SCALED_RESOLVE: |
105 | case PIPE_CAP_SCALED_RESOLVE: |
106 | case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
106 | case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
107 | return 1; |
107 | return 1; |
108 | case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: |
108 | case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: |
109 | return 65536; |
109 | return 65536; |
110 | case PIPE_CAP_SEAMLESS_CUBE_MAP: |
110 | case PIPE_CAP_SEAMLESS_CUBE_MAP: |
111 | return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS; |
111 | return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS; |
112 | case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
112 | case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
113 | return 0; |
113 | return 0; |
114 | case PIPE_CAP_CUBE_MAP_ARRAY: |
114 | case PIPE_CAP_CUBE_MAP_ARRAY: |
115 | return 0; |
115 | return 0; |
116 | /* |
116 | /* |
117 | return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; |
117 | return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; |
118 | */ |
118 | */ |
119 | case PIPE_CAP_TWO_SIDED_STENCIL: |
119 | case PIPE_CAP_TWO_SIDED_STENCIL: |
120 | case PIPE_CAP_DEPTH_CLIP_DISABLE: |
120 | case PIPE_CAP_DEPTH_CLIP_DISABLE: |
121 | case PIPE_CAP_POINT_SPRITE: |
121 | case PIPE_CAP_POINT_SPRITE: |
122 | return 1; |
122 | return 1; |
123 | case PIPE_CAP_SM3: |
123 | case PIPE_CAP_SM3: |
124 | return 1; |
124 | return 1; |
125 | case PIPE_CAP_GLSL_FEATURE_LEVEL: |
125 | case PIPE_CAP_GLSL_FEATURE_LEVEL: |
126 | return 140; |
126 | return 140; |
127 | case PIPE_CAP_MAX_RENDER_TARGETS: |
127 | case PIPE_CAP_MAX_RENDER_TARGETS: |
128 | return 8; |
128 | return 8; |
129 | case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
129 | case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
130 | return 1; |
130 | return 1; |
131 | case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: |
131 | case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: |
132 | case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
132 | case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
133 | case PIPE_CAP_VERTEX_COLOR_CLAMPED: |
133 | case PIPE_CAP_VERTEX_COLOR_CLAMPED: |
134 | return 1; |
134 | return 1; |
135 | case PIPE_CAP_QUERY_TIMESTAMP: |
135 | case PIPE_CAP_QUERY_TIMESTAMP: |
136 | case PIPE_CAP_QUERY_TIME_ELAPSED: |
136 | case PIPE_CAP_QUERY_TIME_ELAPSED: |
137 | case PIPE_CAP_OCCLUSION_QUERY: |
137 | case PIPE_CAP_OCCLUSION_QUERY: |
138 | return 1; |
138 | return 1; |
139 | case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
139 | case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
140 | return 4; |
140 | return 4; |
141 | case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
141 | case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
142 | case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
142 | case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
143 | return 64; |
143 | return 64; |
144 | case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
144 | case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
145 | return (class_3d >= NVA0_3D_CLASS) ? 1 : 0; |
145 | return (class_3d >= NVA0_3D_CLASS) ? 1 : 0; |
146 | case PIPE_CAP_BLEND_EQUATION_SEPARATE: |
146 | case PIPE_CAP_BLEND_EQUATION_SEPARATE: |
147 | case PIPE_CAP_INDEP_BLEND_ENABLE: |
147 | case PIPE_CAP_INDEP_BLEND_ENABLE: |
148 | return 1; |
148 | return 1; |
149 | case PIPE_CAP_INDEP_BLEND_FUNC: |
149 | case PIPE_CAP_INDEP_BLEND_FUNC: |
150 | return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; |
150 | return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; |
151 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
151 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
152 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
152 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
153 | return 1; |
153 | return 1; |
154 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
154 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
155 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
155 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
156 | return 0; |
156 | return 0; |
157 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
157 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
158 | return 0; |
158 | return 0; |
159 | case PIPE_CAP_PRIMITIVE_RESTART: |
159 | case PIPE_CAP_PRIMITIVE_RESTART: |
160 | case PIPE_CAP_TGSI_INSTANCEID: |
160 | case PIPE_CAP_TGSI_INSTANCEID: |
161 | case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: |
161 | case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: |
162 | case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
162 | case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
163 | case PIPE_CAP_CONDITIONAL_RENDER: |
163 | case PIPE_CAP_CONDITIONAL_RENDER: |
164 | case PIPE_CAP_TEXTURE_BARRIER: |
164 | case PIPE_CAP_TEXTURE_BARRIER: |
165 | case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
165 | case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
166 | case PIPE_CAP_START_INSTANCE: |
166 | case PIPE_CAP_START_INSTANCE: |
167 | return 1; |
167 | return 1; |
168 | case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
168 | case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
169 | return 0; /* state trackers will know better */ |
169 | return 0; /* state trackers will know better */ |
170 | case PIPE_CAP_USER_CONSTANT_BUFFERS: |
170 | case PIPE_CAP_USER_CONSTANT_BUFFERS: |
171 | case PIPE_CAP_USER_INDEX_BUFFERS: |
171 | case PIPE_CAP_USER_INDEX_BUFFERS: |
172 | case PIPE_CAP_USER_VERTEX_BUFFERS: |
172 | case PIPE_CAP_USER_VERTEX_BUFFERS: |
173 | return 1; |
173 | return 1; |
174 | case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
174 | case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
175 | return 256; |
175 | return 256; |
176 | case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: |
176 | case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: |
177 | return 1; /* 256 for binding as RT, but that's not possible in GL */ |
177 | return 1; /* 256 for binding as RT, but that's not possible in GL */ |
178 | case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
178 | case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
179 | return NOUVEAU_MIN_BUFFER_MAP_ALIGN; |
179 | return NOUVEAU_MIN_BUFFER_MAP_ALIGN; |
180 | case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
180 | case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
181 | case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
181 | case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
182 | case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
182 | case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
183 | case PIPE_CAP_TGSI_TEXCOORD: |
183 | case PIPE_CAP_TGSI_TEXCOORD: |
184 | case PIPE_CAP_TEXTURE_MULTISAMPLE: |
184 | case PIPE_CAP_TEXTURE_MULTISAMPLE: |
185 | return 0; |
185 | return 0; |
186 | case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
186 | case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
187 | return 1; |
187 | return 1; |
188 | case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
188 | case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
189 | return 0; |
189 | return 0; |
190 | case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
190 | case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
191 | return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50; |
191 | return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50; |
192 | case PIPE_CAP_ENDIANNESS: |
192 | case PIPE_CAP_ENDIANNESS: |
193 | return PIPE_ENDIAN_LITTLE; |
193 | return PIPE_ENDIAN_LITTLE; |
194 | default: |
194 | default: |
195 | NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); |
195 | NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); |
196 | return 0; |
196 | return 0; |
197 | } |
197 | } |
198 | } |
198 | } |
199 | 199 | ||
200 | static int |
200 | static int |
201 | nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, |
201 | nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, |
202 | enum pipe_shader_cap param) |
202 | enum pipe_shader_cap param) |
203 | { |
203 | { |
204 | switch (shader) { |
204 | switch (shader) { |
205 | case PIPE_SHADER_VERTEX: |
205 | case PIPE_SHADER_VERTEX: |
206 | case PIPE_SHADER_GEOMETRY: |
206 | case PIPE_SHADER_GEOMETRY: |
207 | case PIPE_SHADER_FRAGMENT: |
207 | case PIPE_SHADER_FRAGMENT: |
208 | break; |
208 | break; |
209 | default: |
209 | default: |
210 | return 0; |
210 | return 0; |
211 | } |
211 | } |
212 | 212 | ||
213 | switch (param) { |
213 | switch (param) { |
214 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
214 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
215 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
215 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
216 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
216 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
217 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
217 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
218 | return 16384; |
218 | return 16384; |
219 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
219 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
220 | return 4; |
220 | return 4; |
221 | case PIPE_SHADER_CAP_MAX_INPUTS: |
221 | case PIPE_SHADER_CAP_MAX_INPUTS: |
222 | if (shader == PIPE_SHADER_VERTEX) |
222 | if (shader == PIPE_SHADER_VERTEX) |
223 | return 32; |
223 | return 32; |
224 | return 0x300 / 16; |
224 | return 15; |
225 | case PIPE_SHADER_CAP_MAX_CONSTS: |
225 | case PIPE_SHADER_CAP_MAX_CONSTS: |
226 | return 65536 / 16; |
226 | return 65536 / 16; |
227 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
227 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
228 | return NV50_MAX_PIPE_CONSTBUFS; |
228 | return NV50_MAX_PIPE_CONSTBUFS; |
229 | case PIPE_SHADER_CAP_MAX_ADDRS: |
229 | case PIPE_SHADER_CAP_MAX_ADDRS: |
230 | return 1; |
230 | return 1; |
231 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
231 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
232 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
232 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
233 | return shader != PIPE_SHADER_FRAGMENT; |
233 | return shader != PIPE_SHADER_FRAGMENT; |
234 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
234 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
235 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
235 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
236 | return 1; |
236 | return 1; |
237 | case PIPE_SHADER_CAP_MAX_PREDS: |
237 | case PIPE_SHADER_CAP_MAX_PREDS: |
238 | return 0; |
238 | return 0; |
239 | case PIPE_SHADER_CAP_MAX_TEMPS: |
239 | case PIPE_SHADER_CAP_MAX_TEMPS: |
240 | return nv50_screen(pscreen)->max_tls_space / ONE_TEMP_SIZE; |
240 | return nv50_screen(pscreen)->max_tls_space / ONE_TEMP_SIZE; |
241 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
241 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
242 | return 1; |
242 | return 1; |
243 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
243 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
244 | return 0; |
244 | return 0; |
245 | case PIPE_SHADER_CAP_SUBROUTINES: |
245 | case PIPE_SHADER_CAP_SUBROUTINES: |
246 | return 0; /* please inline, or provide function declarations */ |
246 | return 0; /* please inline, or provide function declarations */ |
247 | case PIPE_SHADER_CAP_INTEGERS: |
247 | case PIPE_SHADER_CAP_INTEGERS: |
248 | return 1; |
248 | return 1; |
249 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
249 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
250 | return 32; |
250 | return 32; |
251 | default: |
251 | default: |
252 | NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); |
252 | NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); |
253 | return 0; |
253 | return 0; |
254 | } |
254 | } |
255 | } |
255 | } |
256 | 256 | ||
257 | static float |
257 | static float |
258 | nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) |
258 | nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) |
259 | { |
259 | { |
260 | switch (param) { |
260 | switch (param) { |
261 | case PIPE_CAPF_MAX_LINE_WIDTH: |
261 | case PIPE_CAPF_MAX_LINE_WIDTH: |
262 | case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
262 | case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
263 | return 10.0f; |
263 | return 10.0f; |
264 | case PIPE_CAPF_MAX_POINT_WIDTH: |
264 | case PIPE_CAPF_MAX_POINT_WIDTH: |
265 | case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
265 | case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
266 | return 64.0f; |
266 | return 64.0f; |
267 | case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
267 | case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
268 | return 16.0f; |
268 | return 16.0f; |
269 | case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
269 | case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
270 | return 4.0f; |
270 | return 4.0f; |
271 | default: |
271 | default: |
272 | NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); |
272 | NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); |
273 | return 0.0f; |
273 | return 0.0f; |
274 | } |
274 | } |
275 | } |
275 | } |
276 | 276 | ||
277 | static void |
277 | static void |
278 | nv50_screen_destroy(struct pipe_screen *pscreen) |
278 | nv50_screen_destroy(struct pipe_screen *pscreen) |
279 | { |
279 | { |
280 | struct nv50_screen *screen = nv50_screen(pscreen); |
280 | struct nv50_screen *screen = nv50_screen(pscreen); |
281 | 281 | ||
282 | if (screen->base.fence.current) { |
282 | if (screen->base.fence.current) { |
283 | nouveau_fence_wait(screen->base.fence.current); |
283 | nouveau_fence_wait(screen->base.fence.current); |
284 | nouveau_fence_ref (NULL, &screen->base.fence.current); |
284 | nouveau_fence_ref (NULL, &screen->base.fence.current); |
285 | } |
285 | } |
286 | if (screen->base.pushbuf) |
286 | if (screen->base.pushbuf) |
287 | screen->base.pushbuf->user_priv = NULL; |
287 | screen->base.pushbuf->user_priv = NULL; |
288 | 288 | ||
289 | if (screen->blitter) |
289 | if (screen->blitter) |
290 | nv50_blitter_destroy(screen); |
290 | nv50_blitter_destroy(screen); |
291 | 291 | ||
292 | nouveau_bo_ref(NULL, &screen->code); |
292 | nouveau_bo_ref(NULL, &screen->code); |
293 | nouveau_bo_ref(NULL, &screen->tls_bo); |
293 | nouveau_bo_ref(NULL, &screen->tls_bo); |
294 | nouveau_bo_ref(NULL, &screen->stack_bo); |
294 | nouveau_bo_ref(NULL, &screen->stack_bo); |
295 | nouveau_bo_ref(NULL, &screen->txc); |
295 | nouveau_bo_ref(NULL, &screen->txc); |
296 | nouveau_bo_ref(NULL, &screen->uniforms); |
296 | nouveau_bo_ref(NULL, &screen->uniforms); |
297 | nouveau_bo_ref(NULL, &screen->fence.bo); |
297 | nouveau_bo_ref(NULL, &screen->fence.bo); |
298 | 298 | ||
299 | nouveau_heap_destroy(&screen->vp_code_heap); |
299 | nouveau_heap_destroy(&screen->vp_code_heap); |
300 | nouveau_heap_destroy(&screen->gp_code_heap); |
300 | nouveau_heap_destroy(&screen->gp_code_heap); |
301 | nouveau_heap_destroy(&screen->fp_code_heap); |
301 | nouveau_heap_destroy(&screen->fp_code_heap); |
302 | 302 | ||
303 | FREE(screen->tic.entries); |
303 | FREE(screen->tic.entries); |
304 | 304 | ||
305 | nouveau_object_del(&screen->tesla); |
305 | nouveau_object_del(&screen->tesla); |
306 | nouveau_object_del(&screen->eng2d); |
306 | nouveau_object_del(&screen->eng2d); |
307 | nouveau_object_del(&screen->m2mf); |
307 | nouveau_object_del(&screen->m2mf); |
308 | nouveau_object_del(&screen->sync); |
308 | nouveau_object_del(&screen->sync); |
309 | 309 | ||
310 | nouveau_screen_fini(&screen->base); |
310 | nouveau_screen_fini(&screen->base); |
311 | 311 | ||
312 | FREE(screen); |
312 | FREE(screen); |
313 | } |
313 | } |
314 | 314 | ||
315 | static void |
315 | static void |
316 | nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) |
316 | nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) |
317 | { |
317 | { |
318 | struct nv50_screen *screen = nv50_screen(pscreen); |
318 | struct nv50_screen *screen = nv50_screen(pscreen); |
319 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
319 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
320 | 320 | ||
321 | /* we need to do it after possible flush in MARK_RING */ |
321 | /* we need to do it after possible flush in MARK_RING */ |
322 | *sequence = ++screen->base.fence.sequence; |
322 | *sequence = ++screen->base.fence.sequence; |
323 | 323 | ||
324 | PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4)); |
324 | PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4)); |
325 | PUSH_DATAh(push, screen->fence.bo->offset); |
325 | PUSH_DATAh(push, screen->fence.bo->offset); |
326 | PUSH_DATA (push, screen->fence.bo->offset); |
326 | PUSH_DATA (push, screen->fence.bo->offset); |
327 | PUSH_DATA (push, *sequence); |
327 | PUSH_DATA (push, *sequence); |
328 | PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | |
328 | PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | |
329 | NV50_3D_QUERY_GET_UNK4 | |
329 | NV50_3D_QUERY_GET_UNK4 | |
330 | NV50_3D_QUERY_GET_UNIT_CROP | |
330 | NV50_3D_QUERY_GET_UNIT_CROP | |
331 | NV50_3D_QUERY_GET_TYPE_QUERY | |
331 | NV50_3D_QUERY_GET_TYPE_QUERY | |
332 | NV50_3D_QUERY_GET_QUERY_SELECT_ZERO | |
332 | NV50_3D_QUERY_GET_QUERY_SELECT_ZERO | |
333 | NV50_3D_QUERY_GET_SHORT); |
333 | NV50_3D_QUERY_GET_SHORT); |
334 | } |
334 | } |
335 | 335 | ||
336 | static u32 |
336 | static u32 |
337 | nv50_screen_fence_update(struct pipe_screen *pscreen) |
337 | nv50_screen_fence_update(struct pipe_screen *pscreen) |
338 | { |
338 | { |
339 | return nv50_screen(pscreen)->fence.map[0]; |
339 | return nv50_screen(pscreen)->fence.map[0]; |
340 | } |
340 | } |
341 | 341 | ||
342 | static void |
342 | static void |
343 | nv50_screen_init_hwctx(struct nv50_screen *screen) |
343 | nv50_screen_init_hwctx(struct nv50_screen *screen) |
344 | { |
344 | { |
345 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
345 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
346 | struct nv04_fifo *fifo; |
346 | struct nv04_fifo *fifo; |
347 | unsigned i; |
347 | unsigned i; |
348 | 348 | ||
349 | fifo = (struct nv04_fifo *)screen->base.channel->data; |
349 | fifo = (struct nv04_fifo *)screen->base.channel->data; |
350 | 350 | ||
351 | BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); |
351 | BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); |
352 | PUSH_DATA (push, screen->m2mf->handle); |
352 | PUSH_DATA (push, screen->m2mf->handle); |
353 | BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3); |
353 | BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3); |
354 | PUSH_DATA (push, screen->sync->handle); |
354 | PUSH_DATA (push, screen->sync->handle); |
355 | PUSH_DATA (push, fifo->vram); |
355 | PUSH_DATA (push, fifo->vram); |
356 | PUSH_DATA (push, fifo->vram); |
356 | PUSH_DATA (push, fifo->vram); |
357 | 357 | ||
358 | BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); |
358 | BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); |
359 | PUSH_DATA (push, screen->eng2d->handle); |
359 | PUSH_DATA (push, screen->eng2d->handle); |
360 | BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4); |
360 | BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4); |
361 | PUSH_DATA (push, screen->sync->handle); |
361 | PUSH_DATA (push, screen->sync->handle); |
362 | PUSH_DATA (push, fifo->vram); |
362 | PUSH_DATA (push, fifo->vram); |
363 | PUSH_DATA (push, fifo->vram); |
363 | PUSH_DATA (push, fifo->vram); |
364 | PUSH_DATA (push, fifo->vram); |
364 | PUSH_DATA (push, fifo->vram); |
365 | BEGIN_NV04(push, NV50_2D(OPERATION), 1); |
365 | BEGIN_NV04(push, NV50_2D(OPERATION), 1); |
366 | PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); |
366 | PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); |
367 | BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); |
367 | BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); |
368 | PUSH_DATA (push, 0); |
368 | PUSH_DATA (push, 0); |
369 | BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); |
369 | BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); |
370 | PUSH_DATA (push, 0); |
370 | PUSH_DATA (push, 0); |
371 | BEGIN_NV04(push, SUBC_2D(0x0888), 1); |
371 | BEGIN_NV04(push, SUBC_2D(0x0888), 1); |
372 | PUSH_DATA (push, 1); |
372 | PUSH_DATA (push, 1); |
373 | 373 | ||
374 | BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); |
374 | BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); |
375 | PUSH_DATA (push, screen->tesla->handle); |
375 | PUSH_DATA (push, screen->tesla->handle); |
376 | 376 | ||
377 | BEGIN_NV04(push, NV50_3D(COND_MODE), 1); |
377 | BEGIN_NV04(push, NV50_3D(COND_MODE), 1); |
378 | PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); |
378 | PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); |
379 | 379 | ||
380 | BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); |
380 | BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); |
381 | PUSH_DATA (push, screen->sync->handle); |
381 | PUSH_DATA (push, screen->sync->handle); |
382 | BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); |
382 | BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); |
383 | for (i = 0; i < 11; ++i) |
383 | for (i = 0; i < 11; ++i) |
384 | PUSH_DATA(push, fifo->vram); |
384 | PUSH_DATA(push, fifo->vram); |
385 | BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); |
385 | BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); |
386 | for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) |
386 | for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) |
387 | PUSH_DATA(push, fifo->vram); |
387 | PUSH_DATA(push, fifo->vram); |
388 | 388 | ||
389 | BEGIN_NV04(push, NV50_3D(REG_MODE), 1); |
389 | BEGIN_NV04(push, NV50_3D(REG_MODE), 1); |
390 | PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED); |
390 | PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED); |
391 | BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1); |
391 | BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1); |
392 | PUSH_DATA (push, 0xf); |
392 | PUSH_DATA (push, 0xf); |
393 | 393 | ||
394 | if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) { |
394 | if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) { |
395 | BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1); |
395 | BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1); |
396 | PUSH_DATA (push, 0x18); |
396 | PUSH_DATA (push, 0x18); |
397 | } |
397 | } |
398 | 398 | ||
399 | BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); |
399 | BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); |
400 | PUSH_DATA (push, 1); |
400 | PUSH_DATA (push, 1); |
401 | 401 | ||
402 | BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1); |
402 | BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1); |
403 | PUSH_DATA (push, 0); |
403 | PUSH_DATA (push, 0); |
404 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); |
404 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); |
405 | PUSH_DATA (push, 0); |
405 | PUSH_DATA (push, 0); |
406 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); |
406 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); |
407 | PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1); |
407 | PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1); |
408 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1); |
408 | BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1); |
409 | PUSH_DATA (push, 0); |
409 | PUSH_DATA (push, 0); |
410 | BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1); |
410 | BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1); |
411 | PUSH_DATA (push, 0); |
411 | PUSH_DATA (push, 0); |
412 | BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1); |
412 | BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1); |
413 | PUSH_DATA (push, 1); |
413 | PUSH_DATA (push, 1); |
414 | 414 | ||
415 | if (screen->tesla->oclass >= NVA0_3D_CLASS) { |
415 | if (screen->tesla->oclass >= NVA0_3D_CLASS) { |
416 | BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1); |
416 | BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1); |
417 | PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); |
417 | PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); |
418 | } |
418 | } |
419 | 419 | ||
420 | BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1); |
420 | BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1); |
421 | PUSH_DATA (push, 0); |
421 | PUSH_DATA (push, 0); |
422 | BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2); |
422 | BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2); |
423 | PUSH_DATA (push, 0); |
423 | PUSH_DATA (push, 0); |
424 | PUSH_DATA (push, 0); |
424 | PUSH_DATA (push, 0); |
425 | BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1); |
425 | BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1); |
426 | PUSH_DATA (push, 0x3f); |
426 | PUSH_DATA (push, 0x3f); |
427 | 427 | ||
428 | BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); |
428 | BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); |
429 | PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); |
429 | PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); |
430 | PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); |
430 | PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); |
431 | 431 | ||
432 | BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); |
432 | BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); |
433 | PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); |
433 | PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); |
434 | PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); |
434 | PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); |
435 | 435 | ||
436 | BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2); |
436 | BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2); |
437 | PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); |
437 | PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); |
438 | PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); |
438 | PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); |
439 | 439 | ||
440 | BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); |
440 | BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); |
441 | PUSH_DATAh(push, screen->tls_bo->offset); |
441 | PUSH_DATAh(push, screen->tls_bo->offset); |
442 | PUSH_DATA (push, screen->tls_bo->offset); |
442 | PUSH_DATA (push, screen->tls_bo->offset); |
443 | PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8)); |
443 | PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8)); |
444 | 444 | ||
445 | BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3); |
445 | BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3); |
446 | PUSH_DATAh(push, screen->stack_bo->offset); |
446 | PUSH_DATAh(push, screen->stack_bo->offset); |
447 | PUSH_DATA (push, screen->stack_bo->offset); |
447 | PUSH_DATA (push, screen->stack_bo->offset); |
448 | PUSH_DATA (push, 4); |
448 | PUSH_DATA (push, 4); |
449 | 449 | ||
450 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
450 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
451 | PUSH_DATAh(push, screen->uniforms->offset + (0 << 16)); |
451 | PUSH_DATAh(push, screen->uniforms->offset + (0 << 16)); |
452 | PUSH_DATA (push, screen->uniforms->offset + (0 << 16)); |
452 | PUSH_DATA (push, screen->uniforms->offset + (0 << 16)); |
453 | PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000); |
453 | PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000); |
454 | 454 | ||
455 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
455 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
456 | PUSH_DATAh(push, screen->uniforms->offset + (1 << 16)); |
456 | PUSH_DATAh(push, screen->uniforms->offset + (1 << 16)); |
457 | PUSH_DATA (push, screen->uniforms->offset + (1 << 16)); |
457 | PUSH_DATA (push, screen->uniforms->offset + (1 << 16)); |
458 | PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000); |
458 | PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000); |
459 | 459 | ||
460 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
460 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
461 | PUSH_DATAh(push, screen->uniforms->offset + (2 << 16)); |
461 | PUSH_DATAh(push, screen->uniforms->offset + (2 << 16)); |
462 | PUSH_DATA (push, screen->uniforms->offset + (2 << 16)); |
462 | PUSH_DATA (push, screen->uniforms->offset + (2 << 16)); |
463 | PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000); |
463 | PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000); |
464 | 464 | ||
465 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
465 | BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); |
466 | PUSH_DATAh(push, screen->uniforms->offset + (3 << 16)); |
466 | PUSH_DATAh(push, screen->uniforms->offset + (3 << 16)); |
467 | PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); |
467 | PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); |
468 | PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); |
468 | PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); |
469 | 469 | ||
470 | BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3); |
470 | BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3); |
471 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); |
471 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); |
472 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); |
472 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); |
473 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); |
473 | PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); |
474 | 474 | ||
475 | /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */ |
475 | /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */ |
476 | BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); |
476 | BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); |
477 | PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX); |
477 | PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX); |
478 | BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4); |
478 | BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4); |
479 | PUSH_DATAf(push, 0.0f); |
479 | PUSH_DATAf(push, 0.0f); |
480 | PUSH_DATAf(push, 0.0f); |
480 | PUSH_DATAf(push, 0.0f); |
481 | PUSH_DATAf(push, 0.0f); |
481 | PUSH_DATAf(push, 0.0f); |
482 | PUSH_DATAf(push, 0.0f); |
482 | PUSH_DATAf(push, 0.0f); |
483 | BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); |
483 | BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); |
484 | PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9)); |
484 | PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9)); |
485 | PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9)); |
485 | PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9)); |
486 | 486 | ||
487 | /* max TIC (bits 4:8) & TSC bindings, per program type */ |
487 | /* max TIC (bits 4:8) & TSC bindings, per program type */ |
488 | for (i = 0; i < 3; ++i) { |
488 | for (i = 0; i < 3; ++i) { |
489 | BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); |
489 | BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); |
490 | PUSH_DATA (push, 0x54); |
490 | PUSH_DATA (push, 0x54); |
491 | } |
491 | } |
492 | 492 | ||
493 | BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); |
493 | BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); |
494 | PUSH_DATAh(push, screen->txc->offset); |
494 | PUSH_DATAh(push, screen->txc->offset); |
495 | PUSH_DATA (push, screen->txc->offset); |
495 | PUSH_DATA (push, screen->txc->offset); |
496 | PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1); |
496 | PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1); |
497 | 497 | ||
498 | BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); |
498 | BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); |
499 | PUSH_DATAh(push, screen->txc->offset + 65536); |
499 | PUSH_DATAh(push, screen->txc->offset + 65536); |
500 | PUSH_DATA (push, screen->txc->offset + 65536); |
500 | PUSH_DATA (push, screen->txc->offset + 65536); |
501 | PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1); |
501 | PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1); |
502 | 502 | ||
503 | BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); |
503 | BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); |
504 | PUSH_DATA (push, 0); |
504 | PUSH_DATA (push, 0); |
505 | 505 | ||
506 | BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1); |
506 | BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1); |
507 | PUSH_DATA (push, 0); |
507 | PUSH_DATA (push, 0); |
508 | BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1); |
508 | BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1); |
509 | PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); |
509 | PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); |
510 | BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2); |
510 | BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2); |
511 | for (i = 0; i < 8 * 2; ++i) |
511 | for (i = 0; i < 8 * 2; ++i) |
512 | PUSH_DATA(push, 0); |
512 | PUSH_DATA(push, 0); |
513 | BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1); |
513 | BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1); |
514 | PUSH_DATA (push, 0); |
514 | PUSH_DATA (push, 0); |
515 | 515 | ||
516 | BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); |
516 | BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); |
517 | PUSH_DATA (push, 1); |
517 | PUSH_DATA (push, 1); |
518 | BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); |
518 | BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); |
519 | PUSH_DATAf(push, 0.0f); |
519 | PUSH_DATAf(push, 0.0f); |
520 | PUSH_DATAf(push, 1.0f); |
520 | PUSH_DATAf(push, 1.0f); |
521 | 521 | ||
522 | BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); |
522 | BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); |
523 | #ifdef NV50_SCISSORS_CLIPPING |
523 | #ifdef NV50_SCISSORS_CLIPPING |
524 | PUSH_DATA (push, 0x0000); |
524 | PUSH_DATA (push, 0x0000); |
525 | #else |
525 | #else |
526 | PUSH_DATA (push, 0x1080); |
526 | PUSH_DATA (push, 0x1080); |
527 | #endif |
527 | #endif |
528 | 528 | ||
529 | BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1); |
529 | BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1); |
530 | PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); |
530 | PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); |
531 | 531 | ||
532 | /* We use scissors instead of exact view volume clipping, |
532 | /* We use scissors instead of exact view volume clipping, |
533 | * so they're always enabled. |
533 | * so they're always enabled. |
534 | */ |
534 | */ |
535 | BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); |
535 | BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); |
536 | PUSH_DATA (push, 1); |
536 | PUSH_DATA (push, 1); |
537 | PUSH_DATA (push, 8192 << 16); |
537 | PUSH_DATA (push, 8192 << 16); |
538 | PUSH_DATA (push, 8192 << 16); |
538 | PUSH_DATA (push, 8192 << 16); |
539 | 539 | ||
540 | BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); |
540 | BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); |
541 | PUSH_DATA (push, 1); |
541 | PUSH_DATA (push, 1); |
542 | BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1); |
542 | BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1); |
543 | PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL); |
543 | PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL); |
544 | BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); |
544 | BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); |
545 | PUSH_DATA (push, 0x11111111); |
545 | PUSH_DATA (push, 0x11111111); |
546 | BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); |
546 | BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); |
547 | PUSH_DATA (push, 1); |
547 | PUSH_DATA (push, 1); |
548 | 548 | ||
549 | PUSH_KICK (push); |
549 | PUSH_KICK (push); |
550 | } |
550 | } |
551 | 551 | ||
552 | static int nv50_tls_alloc(struct nv50_screen *screen, unsigned tls_space, |
552 | static int nv50_tls_alloc(struct nv50_screen *screen, unsigned tls_space, |
553 | uint64_t *tls_size) |
553 | uint64_t *tls_size) |
554 | { |
554 | { |
555 | struct nouveau_device *dev = screen->base.device; |
555 | struct nouveau_device *dev = screen->base.device; |
556 | int ret; |
556 | int ret; |
557 | 557 | ||
558 | screen->cur_tls_space = util_next_power_of_two(tls_space / ONE_TEMP_SIZE) * |
558 | screen->cur_tls_space = util_next_power_of_two(tls_space / ONE_TEMP_SIZE) * |
559 | ONE_TEMP_SIZE; |
559 | ONE_TEMP_SIZE; |
560 | if (nouveau_mesa_debug) |
560 | if (nouveau_mesa_debug) |
561 | debug_printf("allocating space for %u temps\n", |
561 | debug_printf("allocating space for %u temps\n", |
562 | util_next_power_of_two(tls_space / ONE_TEMP_SIZE)); |
562 | util_next_power_of_two(tls_space / ONE_TEMP_SIZE)); |
563 | *tls_size = screen->cur_tls_space * util_next_power_of_two(screen->TPs) * |
563 | *tls_size = screen->cur_tls_space * util_next_power_of_two(screen->TPs) * |
564 | screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP; |
564 | screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP; |
565 | 565 | ||
566 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, |
566 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, |
567 | *tls_size, NULL, &screen->tls_bo); |
567 | *tls_size, NULL, &screen->tls_bo); |
568 | if (ret) { |
568 | if (ret) { |
569 | NOUVEAU_ERR("Failed to allocate local bo: %d\n", ret); |
569 | NOUVEAU_ERR("Failed to allocate local bo: %d\n", ret); |
570 | return ret; |
570 | return ret; |
571 | } |
571 | } |
572 | 572 | ||
573 | return 0; |
573 | return 0; |
574 | } |
574 | } |
575 | 575 | ||
576 | int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space) |
576 | int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space) |
577 | { |
577 | { |
578 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
578 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
579 | int ret; |
579 | int ret; |
580 | uint64_t tls_size; |
580 | uint64_t tls_size; |
581 | 581 | ||
582 | if (tls_space < screen->cur_tls_space) |
582 | if (tls_space < screen->cur_tls_space) |
583 | return 0; |
583 | return 0; |
584 | if (tls_space > screen->max_tls_space) { |
584 | if (tls_space > screen->max_tls_space) { |
585 | /* fixable by limiting number of warps (LOCAL_WARPS_LOG_ALLOC / |
585 | /* fixable by limiting number of warps (LOCAL_WARPS_LOG_ALLOC / |
586 | * LOCAL_WARPS_NO_CLAMP) */ |
586 | * LOCAL_WARPS_NO_CLAMP) */ |
587 | NOUVEAU_ERR("Unsupported number of temporaries (%u > %u). Fixable if someone cares.\n", |
587 | NOUVEAU_ERR("Unsupported number of temporaries (%u > %u). Fixable if someone cares.\n", |
588 | (unsigned)(tls_space / ONE_TEMP_SIZE), |
588 | (unsigned)(tls_space / ONE_TEMP_SIZE), |
589 | (unsigned)(screen->max_tls_space / ONE_TEMP_SIZE)); |
589 | (unsigned)(screen->max_tls_space / ONE_TEMP_SIZE)); |
590 | return -ENOMEM; |
590 | return -ENOMEM; |
591 | } |
591 | } |
592 | 592 | ||
593 | nouveau_bo_ref(NULL, &screen->tls_bo); |
593 | nouveau_bo_ref(NULL, &screen->tls_bo); |
594 | ret = nv50_tls_alloc(screen, tls_space, &tls_size); |
594 | ret = nv50_tls_alloc(screen, tls_space, &tls_size); |
595 | if (ret) |
595 | if (ret) |
596 | return ret; |
596 | return ret; |
597 | 597 | ||
598 | BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); |
598 | BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); |
599 | PUSH_DATAh(push, screen->tls_bo->offset); |
599 | PUSH_DATAh(push, screen->tls_bo->offset); |
600 | PUSH_DATA (push, screen->tls_bo->offset); |
600 | PUSH_DATA (push, screen->tls_bo->offset); |
601 | PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8)); |
601 | PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8)); |
602 | 602 | ||
603 | return 1; |
603 | return 1; |
604 | } |
604 | } |
605 | 605 | ||
606 | struct pipe_screen * |
606 | struct pipe_screen * |
607 | nv50_screen_create(struct nouveau_device *dev) |
607 | nv50_screen_create(struct nouveau_device *dev) |
608 | { |
608 | { |
609 | struct nv50_screen *screen; |
609 | struct nv50_screen *screen; |
610 | struct pipe_screen *pscreen; |
610 | struct pipe_screen *pscreen; |
611 | struct nouveau_object *chan; |
611 | struct nouveau_object *chan; |
612 | uint64_t value; |
612 | uint64_t value; |
613 | uint32_t tesla_class; |
613 | uint32_t tesla_class; |
614 | unsigned stack_size; |
614 | unsigned stack_size; |
615 | int ret; |
615 | int ret; |
616 | 616 | ||
617 | screen = CALLOC_STRUCT(nv50_screen); |
617 | screen = CALLOC_STRUCT(nv50_screen); |
618 | if (!screen) |
618 | if (!screen) |
619 | return NULL; |
619 | return NULL; |
620 | pscreen = &screen->base.base; |
620 | pscreen = &screen->base.base; |
621 | 621 | ||
622 | ret = nouveau_screen_init(&screen->base, dev); |
622 | ret = nouveau_screen_init(&screen->base, dev); |
623 | if (ret) { |
623 | if (ret) { |
624 | NOUVEAU_ERR("nouveau_screen_init failed: %d\n", ret); |
624 | NOUVEAU_ERR("nouveau_screen_init failed: %d\n", ret); |
625 | goto fail; |
625 | goto fail; |
626 | } |
626 | } |
627 | 627 | ||
628 | /* TODO: Prevent FIFO prefetch before transfer of index buffers and |
628 | /* TODO: Prevent FIFO prefetch before transfer of index buffers and |
629 | * admit them to VRAM. |
629 | * admit them to VRAM. |
630 | */ |
630 | */ |
631 | screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER | |
631 | screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER | |
632 | PIPE_BIND_VERTEX_BUFFER; |
632 | PIPE_BIND_VERTEX_BUFFER; |
633 | screen->base.sysmem_bindings |= |
633 | screen->base.sysmem_bindings |= |
634 | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; |
634 | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; |
635 | 635 | ||
636 | screen->base.pushbuf->user_priv = screen; |
636 | screen->base.pushbuf->user_priv = screen; |
637 | screen->base.pushbuf->rsvd_kick = 5; |
637 | screen->base.pushbuf->rsvd_kick = 5; |
638 | 638 | ||
639 | chan = screen->base.channel; |
639 | chan = screen->base.channel; |
640 | 640 | ||
641 | pscreen->destroy = nv50_screen_destroy; |
641 | pscreen->destroy = nv50_screen_destroy; |
642 | pscreen->context_create = nv50_create; |
642 | pscreen->context_create = nv50_create; |
643 | pscreen->is_format_supported = nv50_screen_is_format_supported; |
643 | pscreen->is_format_supported = nv50_screen_is_format_supported; |
644 | pscreen->get_param = nv50_screen_get_param; |
644 | pscreen->get_param = nv50_screen_get_param; |
645 | pscreen->get_shader_param = nv50_screen_get_shader_param; |
645 | pscreen->get_shader_param = nv50_screen_get_shader_param; |
646 | pscreen->get_paramf = nv50_screen_get_paramf; |
646 | pscreen->get_paramf = nv50_screen_get_paramf; |
647 | 647 | ||
648 | nv50_screen_init_resource_functions(pscreen); |
648 | nv50_screen_init_resource_functions(pscreen); |
649 | 649 | ||
650 | if (screen->base.device->chipset < 0x84) { |
650 | if (screen->base.device->chipset < 0x84) { |
651 | /* PMPEG */ |
651 | /* PMPEG */ |
652 | nouveau_screen_init_vdec(&screen->base); |
652 | nouveau_screen_init_vdec(&screen->base); |
653 | } else if (screen->base.device->chipset < 0x98 || |
653 | } else if (screen->base.device->chipset < 0x98 || |
654 | screen->base.device->chipset == 0xa0) { |
654 | screen->base.device->chipset == 0xa0) { |
655 | /* VP2 */ |
655 | /* VP2 */ |
656 | screen->base.base.get_video_param = nv84_screen_get_video_param; |
656 | screen->base.base.get_video_param = nv84_screen_get_video_param; |
657 | screen->base.base.is_video_format_supported = nv84_screen_video_supported; |
657 | screen->base.base.is_video_format_supported = nv84_screen_video_supported; |
658 | } else { |
658 | } else { |
659 | /* Unsupported, but need to init pointers. */ |
659 | /* Unsupported, but need to init pointers. */ |
660 | nouveau_screen_init_vdec(&screen->base); |
660 | nouveau_screen_init_vdec(&screen->base); |
661 | } |
661 | } |
662 | 662 | ||
663 | ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, |
663 | ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, |
664 | NULL, &screen->fence.bo); |
664 | NULL, &screen->fence.bo); |
665 | if (ret) { |
665 | if (ret) { |
666 | NOUVEAU_ERR("Failed to allocate fence bo: %d\n", ret); |
666 | NOUVEAU_ERR("Failed to allocate fence bo: %d\n", ret); |
667 | goto fail; |
667 | goto fail; |
668 | } |
668 | } |
669 | 669 | ||
670 | nouveau_bo_map(screen->fence.bo, 0, NULL); |
670 | nouveau_bo_map(screen->fence.bo, 0, NULL); |
671 | screen->fence.map = screen->fence.bo->map; |
671 | screen->fence.map = screen->fence.bo->map; |
672 | screen->base.fence.emit = nv50_screen_fence_emit; |
672 | screen->base.fence.emit = nv50_screen_fence_emit; |
673 | screen->base.fence.update = nv50_screen_fence_update; |
673 | screen->base.fence.update = nv50_screen_fence_update; |
674 | 674 | ||
675 | ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS, |
675 | ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS, |
676 | &(struct nv04_notify){ .length = 32 }, |
676 | &(struct nv04_notify){ .length = 32 }, |
677 | sizeof(struct nv04_notify), &screen->sync); |
677 | sizeof(struct nv04_notify), &screen->sync); |
678 | if (ret) { |
678 | if (ret) { |
679 | NOUVEAU_ERR("Failed to allocate notifier: %d\n", ret); |
679 | NOUVEAU_ERR("Failed to allocate notifier: %d\n", ret); |
680 | goto fail; |
680 | goto fail; |
681 | } |
681 | } |
682 | 682 | ||
683 | ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS, |
683 | ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS, |
684 | NULL, 0, &screen->m2mf); |
684 | NULL, 0, &screen->m2mf); |
685 | if (ret) { |
685 | if (ret) { |
686 | NOUVEAU_ERR("Failed to allocate PGRAPH context for M2MF: %d\n", ret); |
686 | NOUVEAU_ERR("Failed to allocate PGRAPH context for M2MF: %d\n", ret); |
687 | goto fail; |
687 | goto fail; |
688 | } |
688 | } |
689 | 689 | ||
690 | ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS, |
690 | ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS, |
691 | NULL, 0, &screen->eng2d); |
691 | NULL, 0, &screen->eng2d); |
692 | if (ret) { |
692 | if (ret) { |
693 | NOUVEAU_ERR("Failed to allocate PGRAPH context for 2D: %d\n", ret); |
693 | NOUVEAU_ERR("Failed to allocate PGRAPH context for 2D: %d\n", ret); |
694 | goto fail; |
694 | goto fail; |
695 | } |
695 | } |
696 | 696 | ||
697 | switch (dev->chipset & 0xf0) { |
697 | switch (dev->chipset & 0xf0) { |
698 | case 0x50: |
698 | case 0x50: |
699 | tesla_class = NV50_3D_CLASS; |
699 | tesla_class = NV50_3D_CLASS; |
700 | break; |
700 | break; |
701 | case 0x80: |
701 | case 0x80: |
702 | case 0x90: |
702 | case 0x90: |
703 | tesla_class = NV84_3D_CLASS; |
703 | tesla_class = NV84_3D_CLASS; |
704 | break; |
704 | break; |
705 | case 0xa0: |
705 | case 0xa0: |
706 | switch (dev->chipset) { |
706 | switch (dev->chipset) { |
707 | case 0xa0: |
707 | case 0xa0: |
708 | case 0xaa: |
708 | case 0xaa: |
709 | case 0xac: |
709 | case 0xac: |
710 | tesla_class = NVA0_3D_CLASS; |
710 | tesla_class = NVA0_3D_CLASS; |
711 | break; |
711 | break; |
712 | case 0xaf: |
712 | case 0xaf: |
713 | tesla_class = NVAF_3D_CLASS; |
713 | tesla_class = NVAF_3D_CLASS; |
714 | break; |
714 | break; |
715 | default: |
715 | default: |
716 | tesla_class = NVA3_3D_CLASS; |
716 | tesla_class = NVA3_3D_CLASS; |
717 | break; |
717 | break; |
718 | } |
718 | } |
719 | break; |
719 | break; |
720 | default: |
720 | default: |
721 | NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", dev->chipset); |
721 | NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", dev->chipset); |
722 | goto fail; |
722 | goto fail; |
723 | } |
723 | } |
724 | screen->base.class_3d = tesla_class; |
724 | screen->base.class_3d = tesla_class; |
725 | 725 | ||
726 | ret = nouveau_object_new(chan, 0xbeef5097, tesla_class, |
726 | ret = nouveau_object_new(chan, 0xbeef5097, tesla_class, |
727 | NULL, 0, &screen->tesla); |
727 | NULL, 0, &screen->tesla); |
728 | if (ret) { |
728 | if (ret) { |
729 | NOUVEAU_ERR("Failed to allocate PGRAPH context for 3D: %d\n", ret); |
729 | NOUVEAU_ERR("Failed to allocate PGRAPH context for 3D: %d\n", ret); |
730 | goto fail; |
730 | goto fail; |
731 | } |
731 | } |
732 | 732 | ||
733 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, |
733 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, |
734 | 3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code); |
734 | 3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code); |
735 | if (ret) { |
735 | if (ret) { |
736 | NOUVEAU_ERR("Failed to allocate code bo: %d\n", ret); |
736 | NOUVEAU_ERR("Failed to allocate code bo: %d\n", ret); |
737 | goto fail; |
737 | goto fail; |
738 | } |
738 | } |
739 | 739 | ||
740 | nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
740 | nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
741 | nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
741 | nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
742 | nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
742 | nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); |
743 | 743 | ||
744 | nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); |
744 | nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); |
745 | 745 | ||
746 | screen->TPs = util_bitcount(value & 0xffff); |
746 | screen->TPs = util_bitcount(value & 0xffff); |
747 | screen->MPsInTP = util_bitcount((value >> 24) & 0xf); |
747 | screen->MPsInTP = util_bitcount((value >> 24) & 0xf); |
748 | 748 | ||
749 | stack_size = util_next_power_of_two(screen->TPs) * screen->MPsInTP * |
749 | stack_size = util_next_power_of_two(screen->TPs) * screen->MPsInTP * |
750 | STACK_WARPS_ALLOC * 64 * 8; |
750 | STACK_WARPS_ALLOC * 64 * 8; |
751 | 751 | ||
752 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL, |
752 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL, |
753 | &screen->stack_bo); |
753 | &screen->stack_bo); |
754 | if (ret) { |
754 | if (ret) { |
755 | NOUVEAU_ERR("Failed to allocate stack bo: %d\n", ret); |
755 | NOUVEAU_ERR("Failed to allocate stack bo: %d\n", ret); |
756 | goto fail; |
756 | goto fail; |
757 | } |
757 | } |
758 | 758 | ||
759 | uint64_t size_of_one_temp = util_next_power_of_two(screen->TPs) * |
759 | uint64_t size_of_one_temp = util_next_power_of_two(screen->TPs) * |
760 | screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP * |
760 | screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP * |
761 | ONE_TEMP_SIZE; |
761 | ONE_TEMP_SIZE; |
762 | screen->max_tls_space = dev->vram_size / size_of_one_temp * ONE_TEMP_SIZE; |
762 | screen->max_tls_space = dev->vram_size / size_of_one_temp * ONE_TEMP_SIZE; |
763 | screen->max_tls_space /= 2; /* half of vram */ |
763 | screen->max_tls_space /= 2; /* half of vram */ |
764 | 764 | ||
765 | /* hw can address max 64 KiB */ |
765 | /* hw can address max 64 KiB */ |
766 | screen->max_tls_space = MIN2(screen->max_tls_space, 64 << 10); |
766 | screen->max_tls_space = MIN2(screen->max_tls_space, 64 << 10); |
767 | 767 | ||
768 | uint64_t tls_size; |
768 | uint64_t tls_size; |
769 | unsigned tls_space = 4/*temps*/ * ONE_TEMP_SIZE; |
769 | unsigned tls_space = 4/*temps*/ * ONE_TEMP_SIZE; |
770 | ret = nv50_tls_alloc(screen, tls_space, &tls_size); |
770 | ret = nv50_tls_alloc(screen, tls_space, &tls_size); |
771 | if (ret) |
771 | if (ret) |
772 | goto fail; |
772 | goto fail; |
773 | 773 | ||
774 | if (nouveau_mesa_debug) |
774 | if (nouveau_mesa_debug) |
775 | debug_printf("TPs = %u, MPsInTP = %u, VRAM = %"PRIu64" MiB, tls_size = %"PRIu64" KiB\n", |
775 | debug_printf("TPs = %u, MPsInTP = %u, VRAM = %"PRIu64" MiB, tls_size = %"PRIu64" KiB\n", |
776 | screen->TPs, screen->MPsInTP, dev->vram_size >> 20, tls_size >> 10); |
776 | screen->TPs, screen->MPsInTP, dev->vram_size >> 20, tls_size >> 10); |
777 | 777 | ||
778 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL, |
778 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL, |
779 | &screen->uniforms); |
779 | &screen->uniforms); |
780 | if (ret) { |
780 | if (ret) { |
781 | NOUVEAU_ERR("Failed to allocate uniforms bo: %d\n", ret); |
781 | NOUVEAU_ERR("Failed to allocate uniforms bo: %d\n", ret); |
782 | goto fail; |
782 | goto fail; |
783 | } |
783 | } |
784 | 784 | ||
785 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL, |
785 | ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL, |
786 | &screen->txc); |
786 | &screen->txc); |
787 | if (ret) { |
787 | if (ret) { |
788 | NOUVEAU_ERR("Failed to allocate TIC/TSC bo: %d\n", ret); |
788 | NOUVEAU_ERR("Failed to allocate TIC/TSC bo: %d\n", ret); |
789 | goto fail; |
789 | goto fail; |
790 | } |
790 | } |
791 | 791 | ||
792 | screen->tic.entries = CALLOC(4096, sizeof(void *)); |
792 | screen->tic.entries = CALLOC(4096, sizeof(void *)); |
793 | screen->tsc.entries = screen->tic.entries + 2048; |
793 | screen->tsc.entries = screen->tic.entries + 2048; |
794 | 794 | ||
795 | if (!nv50_blitter_create(screen)) |
795 | if (!nv50_blitter_create(screen)) |
796 | goto fail; |
796 | goto fail; |
797 | 797 | ||
798 | nv50_screen_init_hwctx(screen); |
798 | nv50_screen_init_hwctx(screen); |
799 | 799 | ||
800 | nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); |
800 | nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); |
801 | 801 | ||
802 | return pscreen; |
802 | return pscreen; |
803 | 803 | ||
804 | fail: |
804 | fail: |
805 | nv50_screen_destroy(pscreen); |
805 | nv50_screen_destroy(pscreen); |
806 | return NULL; |
806 | return NULL; |
807 | } |
807 | } |
808 | 808 | ||
809 | int |
809 | int |
810 | nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry) |
810 | nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry) |
811 | { |
811 | { |
812 | int i = screen->tic.next; |
812 | int i = screen->tic.next; |
813 | 813 | ||
814 | while (screen->tic.lock[i / 32] & (1 << (i % 32))) |
814 | while (screen->tic.lock[i / 32] & (1 << (i % 32))) |
815 | i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); |
815 | i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); |
816 | 816 | ||
817 | screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); |
817 | screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); |
818 | 818 | ||
819 | if (screen->tic.entries[i]) |
819 | if (screen->tic.entries[i]) |
820 | nv50_tic_entry(screen->tic.entries[i])->id = -1; |
820 | nv50_tic_entry(screen->tic.entries[i])->id = -1; |
821 | 821 | ||
822 | screen->tic.entries[i] = entry; |
822 | screen->tic.entries[i] = entry; |
823 | return i; |
823 | return i; |
824 | } |
824 | } |
825 | 825 | ||
826 | int |
826 | int |
827 | nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry) |
827 | nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry) |
828 | { |
828 | { |
829 | int i = screen->tsc.next; |
829 | int i = screen->tsc.next; |
830 | 830 | ||
831 | while (screen->tsc.lock[i / 32] & (1 << (i % 32))) |
831 | while (screen->tsc.lock[i / 32] & (1 << (i % 32))) |
832 | i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); |
832 | i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); |
833 | 833 | ||
834 | screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); |
834 | screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); |
835 | 835 | ||
836 | if (screen->tsc.entries[i]) |
836 | if (screen->tsc.entries[i]) |
837 | nv50_tsc_entry(screen->tsc.entries[i])->id = -1; |
837 | nv50_tsc_entry(screen->tsc.entries[i])->id = -1; |
838 | 838 | ||
839 | screen->tsc.entries[i] = entry; |
839 | screen->tsc.entries[i] = entry; |
840 | return i; |
840 | return i; |
841 | }><>><>><>><>><>><>><>><>><>><>><>><>><>>>>><>><>><>>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>>>>><> |
841 | }><>><>><>><>><>><>><>><>><>><>><>><>><>>>>><>><>><>>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>>>>><> |