X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsoftpipe%2Fsp_state_fs.c;h=ded242d3dc54219b145faabdc920a6b73d4e6c21;hb=c0f0eb866880ff3e701cd3a532d49417f2743283;hp=256faa94b84207cda61ca4b27bdb712cd3a4a8eb;hpb=898de4a9d5e47ed32c600e5907476fd9338aa7e9;p=mesa.git diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 256faa94b84..ded242d3dc5 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -28,12 +28,16 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" +#include "sp_texture.h" #include "pipe/p_defines.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" #include "draw/draw_vs.h" +#include "draw/draw_gs.h" #include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_parse.h" @@ -44,6 +48,7 @@ softpipe_create_fs_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state; + unsigned i; /* debug */ if (softpipe->dump_fs) @@ -60,6 +65,13 @@ softpipe_create_fs_state(struct pipe_context *pipe, /* get/save the summary info for this shader */ tgsi_scan_shader(templ->tokens, &state->info); + for (i = 0; i < state->info.num_properties; ++i) { + if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN) + state->origin_lower_left = state->info.properties[i].data[0]; + else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER) + state->pixel_center_integer = state->info.properties[i].data[0]; + } + return state; } @@ -69,7 +81,14 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->fs = (struct sp_fragment_shader *) fs; + draw_flush(softpipe->draw); + + if (softpipe->fs == fs) + return; + + draw_flush(softpipe->draw); + + softpipe->fs = fs; softpipe->dirty |= SP_NEW_FS; } @@ -78,10 +97,18 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe_context(pipe)->fs); - + + if (softpipe->fs_machine->Tokens == state->shader.tokens) { + /* unbind the shader from the tgsi executor if we're + * deleting it. + */ + tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL); + } + state->delete( state ); } @@ -143,24 +170,99 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs; draw_delete_vertex_shader(softpipe->draw, state->draw_data); + FREE( (void *)state->shader.tokens ); FREE( state ); } - - void softpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_resource *constants) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned size = constants ? constants->width0 : 0; + const void *data = constants ? softpipe_resource(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); + + draw_flush(softpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&softpipe->constants[shader].buffer, - buf ? buf->buffer : NULL); + pipe_resource_reference(&softpipe->constants[shader][index], constants); + + if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { + draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); + } + + softpipe->mapped_constants[shader][index] = data; + softpipe->const_buffer_size[shader][index] = size; softpipe->dirty |= SP_NEW_CONSTANTS; } + + +void * +softpipe_create_gs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct sp_geometry_shader *state; + + state = CALLOC_STRUCT(sp_geometry_shader); + if (state == NULL ) + goto fail; + + /* debug */ + if (softpipe->dump_gs) + tgsi_dump(templ->tokens, 0); + + /* copy shader tokens, the ones passed in will go away. + */ + state->shader.tokens = tgsi_dup_tokens(templ->tokens); + if (state->shader.tokens == NULL) + goto fail; + + state->draw_data = draw_create_geometry_shader(softpipe->draw, templ); + if (state->draw_data == NULL) + goto fail; + + state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; + + return state; + +fail: + if (state) { + FREE( (void *)state->shader.tokens ); + FREE( state->draw_data ); + FREE( state ); + } + return NULL; +} + + +void +softpipe_bind_gs_state(struct pipe_context *pipe, void *gs) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->gs = (struct sp_geometry_shader *)gs; + + draw_bind_geometry_shader(softpipe->draw, + (softpipe->gs ? softpipe->gs->draw_data : NULL)); + + softpipe->dirty |= SP_NEW_GS; +} + + +void +softpipe_delete_gs_state(struct pipe_context *pipe, void *gs) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + struct sp_geometry_shader *state = + (struct sp_geometry_shader *)gs; + + draw_delete_geometry_shader(softpipe->draw, + (state) ? state->draw_data : 0); + FREE(state); +}