X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fdraw%2Fdraw_context.c;h=9de40d76221b4451899becabc5b8c05fd20e2fcd;hb=dc2357070cb78497686d5d3b02418032dddac5ac;hp=85f8e26eb33cbdb1d7bf204e2d3008063ea61f34;hpb=4a38b154fd02061d8989f8973fbc10740300bf8b;p=mesa.git diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 85f8e26eb33..9de40d76221 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -53,20 +53,7 @@ boolean draw_get_option_use_llvm(void) { - static boolean first = TRUE; - static boolean value; - if (first) { - first = FALSE; - value = debug_get_bool_option("DRAW_USE_LLVM", TRUE); - -#ifdef PIPE_ARCH_X86 - util_cpu_detect(); - /* require SSE2 due to LLVM PR6960. XXX Might be fixed by now? */ - if (!util_cpu_caps.has_sse2) - value = FALSE; -#endif - } - return value; + return debug_get_bool_option("DRAW_USE_LLVM", TRUE); } #else boolean @@ -81,10 +68,11 @@ draw_get_option_use_llvm(void) * Create new draw module context with gallivm state for LLVM JIT. */ static struct draw_context * -draw_create_context(struct pipe_context *pipe, boolean try_llvm) +draw_create_context(struct pipe_context *pipe, void *context, + boolean try_llvm) { struct draw_context *draw = CALLOC_STRUCT( draw_context ); - if (draw == NULL) + if (!draw) goto err_out; /* we need correct cpu caps for disabling denorms in draw_vbo() */ @@ -92,7 +80,7 @@ draw_create_context(struct pipe_context *pipe, boolean try_llvm) #if HAVE_LLVM if (try_llvm && draw_get_option_use_llvm()) { - draw->llvm = draw_llvm_create(draw); + draw->llvm = draw_llvm_create(draw, (LLVMContextRef)context); } #endif @@ -120,17 +108,26 @@ err_out: struct draw_context * draw_create(struct pipe_context *pipe) { - return draw_create_context(pipe, TRUE); + return draw_create_context(pipe, NULL, TRUE); } +#if HAVE_LLVM +struct draw_context * +draw_create_with_llvm_context(struct pipe_context *pipe, + void *context) +{ + return draw_create_context(pipe, context, TRUE); +} +#endif + /** * Create a new draw context, without LLVM JIT. */ struct draw_context * draw_create_no_llvm(struct pipe_context *pipe) { - return draw_create_context(pipe, FALSE); + return draw_create_context(pipe, NULL, FALSE); } @@ -185,6 +182,7 @@ boolean draw_init(struct draw_context *draw) void draw_new_instance(struct draw_context *draw) { draw_geometry_shader_new_instance(draw->gs.geometry_shader); + draw_prim_assembler_new_instance(draw->ia); } @@ -208,9 +206,8 @@ void draw_destroy( struct draw_context *draw ) } } - for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { - pipe_resource_reference(&draw->pt.vertex_buffer[i].buffer, NULL); - } + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) + pipe_vertex_buffer_unreference(&draw->pt.vertex_buffer[i]); /* Not so fast -- we're just borrowing this at the moment. * @@ -257,21 +254,48 @@ void draw_set_zs_format(struct draw_context *draw, enum pipe_format format) } -static void update_clip_flags( struct draw_context *draw ) +static bool +draw_is_vs_window_space(struct draw_context *draw) { - draw->clip_xy = !draw->driver.bypass_clip_xy; + if (draw->vs.vertex_shader) { + struct tgsi_shader_info *info = &draw->vs.vertex_shader->info; + + return info->properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION] != 0; + } + return false; +} + + +void +draw_update_clip_flags(struct draw_context *draw) +{ + bool window_space = draw_is_vs_window_space(draw); + + draw->clip_xy = !draw->driver.bypass_clip_xy && !window_space; draw->guard_band_xy = (!draw->driver.bypass_clip_xy && draw->driver.guard_band_xy); draw->clip_z = (!draw->driver.bypass_clip_z && - draw->rasterizer && draw->rasterizer->depth_clip); + draw->rasterizer && draw->rasterizer->depth_clip_near) && + !window_space; draw->clip_user = draw->rasterizer && - draw->rasterizer->clip_plane_enable != 0; + draw->rasterizer->clip_plane_enable != 0 && + !window_space; draw->guard_band_points_xy = draw->guard_band_xy || (draw->driver.bypass_clip_points && (draw->rasterizer && draw->rasterizer->point_tri_clip)); } + +void +draw_update_viewport_flags(struct draw_context *draw) +{ + bool window_space = draw_is_vs_window_space(draw); + + draw->bypass_viewport = window_space || draw->identity_viewport; +} + + /** * Register new primitive rasterization/rendering state. * This causes the drawing pipeline to be rebuilt. @@ -285,7 +309,7 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw->rasterizer = raster; draw->rast_handle = rast_handle; - update_clip_flags(draw); + draw_update_clip_flags(draw); } } @@ -312,7 +336,7 @@ void draw_set_driver_clipping( struct draw_context *draw, draw->driver.bypass_clip_z = bypass_clip_z; draw->driver.guard_band_xy = guard_band_xy; draw->driver.bypass_clip_points = bypass_clip_points; - update_clip_flags(draw); + draw_update_clip_flags(draw); } @@ -363,11 +387,10 @@ void draw_set_viewport_states( struct draw_context *draw, (viewport->scale[0] == 1.0f && viewport->scale[1] == 1.0f && viewport->scale[2] == 1.0f && - viewport->scale[3] == 1.0f && viewport->translate[0] == 0.0f && viewport->translate[1] == 0.0f && - viewport->translate[2] == 0.0f && - viewport->translate[3] == 0.0f); + viewport->translate[2] == 0.0f); + draw_update_viewport_flags(draw); } @@ -416,7 +439,7 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, - unsigned shader_type, + enum pipe_shader_type shader_type, unsigned slot, const void *buffer, unsigned size ) @@ -441,6 +464,32 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, } } +void +draw_set_mapped_shader_buffer(struct draw_context *draw, + enum pipe_shader_type shader_type, + unsigned slot, + const void *buffer, + unsigned size ) +{ + debug_assert(shader_type == PIPE_SHADER_VERTEX || + shader_type == PIPE_SHADER_GEOMETRY); + debug_assert(slot < PIPE_MAX_SHADER_BUFFERS); + + draw_do_flush(draw, DRAW_FLUSH_PARAMETER_CHANGE); + + switch (shader_type) { + case PIPE_SHADER_VERTEX: + draw->pt.user.vs_ssbos[slot] = buffer; + draw->pt.user.vs_ssbos_size[slot] = size; + break; + case PIPE_SHADER_GEOMETRY: + draw->pt.user.gs_ssbos[slot] = buffer; + draw->pt.user.gs_ssbos_size[slot] = size; + break; + default: + assert(0 && "invalid shader type in draw_set_mapped_shader_buffer"); + } +} /** * Tells the draw module to draw points with triangles if their size @@ -532,7 +581,7 @@ draw_alloc_extra_vertex_attrib(struct draw_context *draw, num_outputs = draw_current_shader_outputs(draw); n = draw->extra_shader_outputs.num; - assert(n < Elements(draw->extra_shader_outputs.semantic_name)); + assert(n < ARRAY_SIZE(draw->extra_shader_outputs.semantic_name)); draw->extra_shader_outputs.semantic_name[n] = semantic_name; draw->extra_shader_outputs.semantic_index[n] = semantic_index; @@ -666,7 +715,7 @@ draw_total_vs_outputs(const struct draw_context *draw) { const struct tgsi_shader_info *info = &draw->vs.vertex_shader->info; - return info->num_outputs + draw->extra_shader_outputs.num;; + return info->num_outputs + draw->extra_shader_outputs.num; } /** @@ -696,7 +745,7 @@ draw_total_gs_outputs(const struct draw_context *draw) */ void draw_texture_sampler(struct draw_context *draw, - uint shader, + enum pipe_shader_type shader, struct tgsi_sampler *sampler) { if (shader == PIPE_SHADER_VERTEX) { @@ -707,7 +756,41 @@ draw_texture_sampler(struct draw_context *draw, } } +/** + * Provide TGSI image objects for vertex/geometry shaders that use + * texture fetches. This state only needs to be set once per context. + * This might only be used by software drivers for the time being. + */ +void +draw_image(struct draw_context *draw, + enum pipe_shader_type shader, + struct tgsi_image *image) +{ + if (shader == PIPE_SHADER_VERTEX) { + draw->vs.tgsi.image = image; + } else { + debug_assert(shader == PIPE_SHADER_GEOMETRY); + draw->gs.tgsi.image = image; + } +} +/** + * Provide TGSI buffer objects for vertex/geometry shaders that use + * load/store/atomic ops. This state only needs to be set once per context. + * This might only be used by software drivers for the time being. + */ +void +draw_buffer(struct draw_context *draw, + enum pipe_shader_type shader, + struct tgsi_buffer *buffer) +{ + if (shader == PIPE_SHADER_VERTEX) { + draw->vs.tgsi.buffer = buffer; + } else { + debug_assert(shader == PIPE_SHADER_GEOMETRY); + draw->gs.tgsi.buffer = buffer; + } +} void draw_set_render( struct draw_context *draw, @@ -720,9 +803,6 @@ void draw_set_render( struct draw_context *draw, /** * Tell the draw module where vertex indexes/elements are located, and * their size (in bytes). - * - * Note: the caller must apply the pipe_index_buffer::offset value to - * the address. The draw module doesn't do that. */ void draw_set_indexes(struct draw_context *draw, @@ -798,7 +878,7 @@ draw_current_shader_viewport_index_output(const struct draw_context *draw) { if (draw->gs.geometry_shader) return draw->gs.geometry_shader->viewport_index_output; - return 0; + return draw->vs.vertex_shader->viewport_index_output; } /** @@ -810,7 +890,7 @@ draw_current_shader_uses_viewport_index(const struct draw_context *draw) { if (draw->gs.geometry_shader) return draw->gs.geometry_shader->info.writes_viewport_index; - return FALSE; + return draw->vs.vertex_shader->info.writes_viewport_index; } @@ -829,12 +909,12 @@ draw_current_shader_clipvertex_output(const struct draw_context *draw) } uint -draw_current_shader_clipdistance_output(const struct draw_context *draw, int index) +draw_current_shader_ccdistance_output(const struct draw_context *draw, int index) { debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT); if (draw->gs.geometry_shader) - return draw->gs.geometry_shader->clipdistance_output[index]; - return draw->vs.clipdistance_output[index]; + return draw->gs.geometry_shader->ccdistance_output[index]; + return draw->vs.ccdistance_output[index]; } @@ -846,16 +926,6 @@ draw_current_shader_num_written_clipdistances(const struct draw_context *draw) return draw->vs.vertex_shader->info.num_written_clipdistance; } - -uint -draw_current_shader_culldistance_output(const struct draw_context *draw, int index) -{ - debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT); - if (draw->gs.geometry_shader) - return draw->gs.geometry_shader->culldistance_output[index]; - return draw->vs.vertex_shader->culldistance_output[index]; -} - uint draw_current_shader_num_written_culldistances(const struct draw_context *draw) { @@ -906,6 +976,8 @@ draw_set_mapped_so_targets(struct draw_context *draw, { int i; + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + for (i = 0; i < num_targets; i++) draw->so.targets[i] = targets[i]; for (i = num_targets; i < PIPE_MAX_SO_BUFFERS; i++) @@ -916,7 +988,7 @@ draw_set_mapped_so_targets(struct draw_context *draw, void draw_set_sampler_views(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_view **views, unsigned num) { @@ -929,7 +1001,7 @@ draw_set_sampler_views(struct draw_context *draw, for (i = 0; i < num; ++i) draw->sampler_views[shader_stage][i] = views[i]; - for (i = num; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; ++i) + for (i = num; i < draw->num_sampler_views[shader_stage]; ++i) draw->sampler_views[shader_stage][i] = NULL; draw->num_sampler_views[shader_stage] = num; @@ -937,7 +1009,7 @@ draw_set_sampler_views(struct draw_context *draw, void draw_set_samplers(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_state **samplers, unsigned num) { @@ -961,9 +1033,30 @@ draw_set_samplers(struct draw_context *draw, #endif } +void +draw_set_images(struct draw_context *draw, + enum pipe_shader_type shader_stage, + struct pipe_image_view *views, + unsigned num) +{ + unsigned i; + + debug_assert(shader_stage < PIPE_SHADER_TYPES); + debug_assert(num <= PIPE_MAX_SHADER_IMAGES); + + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + for (i = 0; i < num; ++i) + draw->images[shader_stage][i] = &views[i]; + for (i = num; i < draw->num_sampler_views[shader_stage]; ++i) + draw->images[shader_stage][i] = NULL; + + draw->num_images[shader_stage] = num; +} + void draw_set_mapped_texture(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, unsigned sview_idx, uint32_t width, uint32_t height, uint32_t depth, uint32_t first_level, uint32_t last_level, @@ -983,12 +1076,33 @@ draw_set_mapped_texture(struct draw_context *draw, #endif } +void +draw_set_mapped_image(struct draw_context *draw, + enum pipe_shader_type shader_stage, + unsigned idx, + uint32_t width, uint32_t height, uint32_t depth, + const void *base_ptr, + uint32_t row_stride, + uint32_t img_stride) +{ +#ifdef HAVE_LLVM + if (draw->llvm) + draw_llvm_set_mapped_image(draw, + shader_stage, + idx, + width, height, depth, + base_ptr, + row_stride, img_stride); +#endif +} + /** * XXX: Results for PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS because there are two * different ways of setting textures, and drivers typically only support one. */ int -draw_get_shader_param_no_llvm(unsigned shader, enum pipe_shader_cap param) +draw_get_shader_param_no_llvm(enum pipe_shader_type shader, + enum pipe_shader_cap param) { switch(shader) { case PIPE_SHADER_VERTEX: @@ -1006,7 +1120,7 @@ draw_get_shader_param_no_llvm(unsigned shader, enum pipe_shader_cap param) * draw_get_shader_param_no_llvm instead. */ int -draw_get_shader_param(unsigned shader, enum pipe_shader_cap param) +draw_get_shader_param(enum pipe_shader_type shader, enum pipe_shader_cap param) { #ifdef HAVE_LLVM