18e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/************************************************************************** 28e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * 3c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 48e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * All Rights Reserved. 58e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * 68e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 78e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * copy of this software and associated documentation files (the 88e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * "Software"), to deal in the Software without restriction, including 98e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * the following conditions: 138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * 148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * The above copyright notice and this permission notice (including the 158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * of the Software. 178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * 188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 208e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * 268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell **************************************************************************/ 278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 286393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell#include "sp_context.h" 296393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell#include "sp_state.h" 30c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell#include "sp_fs.h" 31287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "sp_texture.h" 328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 33c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian#include "pipe/p_defines.h" 344f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 3528486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h" 3657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul#include "util/u_pstipple.h" 376ac2c1cc0cd1253ba2014d459010032127f185ecKeith Whitwell#include "draw/draw_context.h" 384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell#include "draw/draw_vs.h" 3953bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin#include "draw/draw_gs.h" 40c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_dump.h" 41c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_scan.h" 42fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell#include "tgsi/tgsi_parse.h" 438e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 45c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul/** 46c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul * Create a new fragment shader variant. 47c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul */ 48c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstatic struct sp_fragment_shader_variant * 49c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulcreate_fs_variant(struct softpipe_context *softpipe, 50c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader *fs, 51c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct sp_fragment_shader_variant_key *key) 52c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul{ 53c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader_variant *var; 5457aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul struct pipe_shader_state *stipple_fs = NULL, *curfs = &fs->shader; 5557aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul unsigned unit = 0; 5657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul 57334a9dd3e60e9c7b8ba7bcceb2c88c2645e6220bBrian Paul#if DO_PSTIPPLE_IN_HELPER_MODULE 5857aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul if (key->polygon_stipple) { 5957aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul /* get new shader that implements polygon stippling */ 6057aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul stipple_fs = util_pstipple_create_fragment_shader(&softpipe->pipe, 6157aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul curfs, &unit); 6257aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul curfs = stipple_fs; 6357aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul } 64334a9dd3e60e9c7b8ba7bcceb2c88c2645e6220bBrian Paul#endif 65c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 66c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* codegen, create variant object */ 674eb3225b38ce12cb34ab3d90804c9683bd7b4ed3José Fonseca var = softpipe_create_fs_variant_exec(softpipe, curfs); 68c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 69c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (var) { 70c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul var->key = *key; 71c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul var->tokens = tgsi_dup_tokens(curfs->tokens); 7257aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul var->stipple_sampler_unit = unit; 73c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 74c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul tgsi_scan_shader(var->tokens, &var->info); 75c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 76c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* See comments elsewhere about draw fragment shaders */ 77c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#if 0 78c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* draw's fs state */ 79c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul var->draw_shader = draw_create_fragment_shader(softpipe->draw, 80c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul &fs->shader); 81c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (!var->draw_shader) { 82c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul var->delete(var); 83c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul FREE((void *) var->tokens); 84c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul return NULL; 85c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul } 86c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#endif 87c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 88c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* insert variant into linked list */ 89c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul var->next = fs->variants; 90c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul fs->variants = var; 91c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul } 92c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 9357aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul if (stipple_fs) { 94f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca FREE((void *) stipple_fs->tokens); 95f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca FREE(stipple_fs); 9657aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul } 9757aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul 98c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul return var; 99c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul} 100c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 101c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 102c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulstruct sp_fragment_shader_variant * 103c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paulsoftpipe_find_fs_variant(struct softpipe_context *sp, 104c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader *fs, 105c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct sp_fragment_shader_variant_key *key) 106c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul{ 107c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader_variant *var; 108c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 109c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul for (var = fs->variants; var; var = var->next) { 110c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (memcmp(&var->key, key, sizeof(*key)) == 0) { 111c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* found it */ 112c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul return var; 113c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul } 114c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul } 115c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 116c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul return create_fs_variant(sp, fs, key); 117c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul} 118c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 119c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 120279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void * 1212b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_create_fs_state(struct pipe_context *pipe, 1222b40838972bb84a0dff8f8a3c933b0d2b8384f10Brian const struct pipe_shader_state *templ) 123ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin{ 124344464bf2e4e151968cfb101c2477e440508b1f0Michel Dänzer struct softpipe_context *softpipe = softpipe_context(pipe); 125c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader); 126344464bf2e4e151968cfb101c2477e440508b1f0Michel Dänzer 127f74279002a0ae0b106bd5410487ef9c0e9b1d8b6Brian /* debug */ 128c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell if (softpipe->dump_fs) 129c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell tgsi_dump(templ->tokens, 0); 13052659e3c238d961de1f25bed9254747f2f931547Brian 131c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* we need to keep a local copy of the tokens */ 132c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul state->shader.tokens = tgsi_dup_tokens(templ->tokens); 133e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul 134e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul /* draw's fs state */ 135c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul state->draw_shader = draw_create_fragment_shader(softpipe->draw, 136c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul &state->shader); 137e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul if (!state->draw_shader) { 138c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul FREE((void *) state->shader.tokens); 139c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul FREE(state); 140e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul return NULL; 141e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul } 142f74279002a0ae0b106bd5410487ef9c0e9b1d8b6Brian 14351345cb3c4d85a9e88ac35b59e938b0692df6205Zack Rusin return state; 144ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin} 145ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin 14652659e3c238d961de1f25bed9254747f2f931547Brian 147279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 1482b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_bind_fs_state(struct pipe_context *pipe, void *fs) 1498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{ 1506393cda6766b707ef01e925d378239a66d143ae0Keith Whitwell struct softpipe_context *softpipe = softpipe_context(pipe); 151c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs; 1528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 1534ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca if (softpipe->fs == fs) 1544ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca return; 1554ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca 1564ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca draw_flush(softpipe->draw); 1574ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca 1584ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca softpipe->fs = fs; 1598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 16016c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul /* This depends on the current fragment shader and must always be 16116c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul * re-validated before use. 16216c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul */ 16316c702ef3b9cff320c2adbfa853e00088adbf689Brian Paul softpipe->fs_variant = NULL; 164c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 165c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (state) 166c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul draw_bind_fragment_shader(softpipe->draw, 167c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul state->draw_shader); 168c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul else 169c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul draw_bind_fragment_shader(softpipe->draw, NULL); 170e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul 171a380f98b6cc1da78d0845746ab86c3490a800126Brian softpipe->dirty |= SP_NEW_FS; 1728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell} 1738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 17452659e3c238d961de1f25bed9254747f2f931547Brian 175279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 1762b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_delete_fs_state(struct pipe_context *pipe, void *fs) 177a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin{ 1781fce9d58cc70deaff284e1d9d0ffcb15b61e7595Brian Paul struct softpipe_context *softpipe = softpipe_context(pipe); 179c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell struct sp_fragment_shader *state = fs; 180c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul struct sp_fragment_shader_variant *var, *next_var; 181ce454d2192918ae4b2535d0e76c68ebde3c4653fBrian Paul 182c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul assert(fs != softpipe->fs); 1831fce9d58cc70deaff284e1d9d0ffcb15b61e7595Brian Paul 184c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* delete variants */ 185c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul for (var = state->variants; var; var = next_var) { 186c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul next_var = var->next; 187c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 188c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul assert(var != softpipe->fs_variant); 189c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 190c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul /* See comments elsewhere about draw fragment shaders */ 191c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#if 0 192c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul draw_delete_fragment_shader(softpipe->draw, var->draw_shader); 193c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul#endif 194c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 195e6e58cfa9dd8cbd5d6977822355d150e76eb987aBrian Paul var->delete(var, softpipe->fs_machine); 196c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul } 197c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 198e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul draw_delete_fragment_shader(softpipe->draw, state->draw_shader); 199e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul 200c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul FREE((void *) state->shader.tokens); 20189d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand FREE(state); 202a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin} 203a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin 204a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin 205279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void * 2062b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_create_vs_state(struct pipe_context *pipe, 2072b40838972bb84a0dff8f8a3c933b0d2b8384f10Brian const struct pipe_shader_state *templ) 208a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin{ 209a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin struct softpipe_context *softpipe = softpipe_context(pipe); 210c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell struct sp_vertex_shader *state; 211ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol 212c04a7f8929d674971a472ffa4d3a31200c22aa5aKeith Whitwell state = CALLOC_STRUCT(sp_vertex_shader); 213fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell if (state == NULL ) 214fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell goto fail; 215fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell 216fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell /* copy shader tokens, the ones passed in will go away. 217fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell */ 218fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell state->shader.tokens = tgsi_dup_tokens(templ->tokens); 219fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell if (state->shader.tokens == NULL) 220fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell goto fail; 221ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol 2229671f7ae476cadb46f9f8f9d0363f24aabaf9f87Brian Paul state->draw_data = draw_create_vertex_shader(softpipe->draw, templ); 223fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell if (state->draw_data == NULL) 224fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell goto fail; 225a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin 2264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; 2274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell 228a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin return state; 229fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell 230fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwellfail: 231fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell if (state) { 232fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell FREE( (void *)state->shader.tokens ); 233fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell FREE( state->draw_data ); 234fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell FREE( state ); 235fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell } 236fa0f48504a32642d688d4b81f62eea54c693b23fKeith Whitwell return NULL; 237a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin} 2388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 23952659e3c238d961de1f25bed9254747f2f931547Brian 240279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 2412b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_bind_vs_state(struct pipe_context *pipe, void *vs) 242de653b4c9bddcec46f3ddf411ec082dd178d7b38Brian{ 243de653b4c9bddcec46f3ddf411ec082dd178d7b38Brian struct softpipe_context *softpipe = softpipe_context(pipe); 2448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 2454256c5829f8c23f8bd5c7c29491210f0f7813bf9Brian Paul softpipe->vs = (struct sp_vertex_shader *) vs; 2460a262998ef2813d19e9fee01d3e5808416e9cb04Brian 247339e7ec6805e6de8794514c0a935081b5d36d38fBrian draw_bind_vertex_shader(softpipe->draw, 248339e7ec6805e6de8794514c0a935081b5d36d38fBrian (softpipe->vs ? softpipe->vs->draw_data : NULL)); 249c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian 250a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin softpipe->dirty |= SP_NEW_VS; 251ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin} 252ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin 25352659e3c238d961de1f25bed9254747f2f931547Brian 254279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 2552b40838972bb84a0dff8f8a3c933b0d2b8384f10Briansoftpipe_delete_vs_state(struct pipe_context *pipe, void *vs) 256901577e07fcab0cf90a272fee900cb0831ae84c3Zack Rusin{ 257a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin struct softpipe_context *softpipe = softpipe_context(pipe); 258a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin 2594256c5829f8c23f8bd5c7c29491210f0f7813bf9Brian Paul struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs; 260a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin 261a1a989f0be8dc34082b52bb3b3a6eacb36d9e75eZack Rusin draw_delete_vertex_shader(softpipe->draw, state->draw_data); 262a24631bcd7ab2cbc6fff2a536502a07a13a9bc83Alan Hourihane FREE( (void *)state->shader.tokens ); 263ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol FREE( state ); 264901577e07fcab0cf90a272fee900cb0831ae84c3Zack Rusin} 2656dcfddb8e2ec2bfb6187b912807fa65f28da2c5eZack Rusin 2664ccf0bb74e7f88ff51bba64a2a94a29f997231f5José Fonseca 267279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void * 26889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_create_gs_state(struct pipe_context *pipe, 26989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin const struct pipe_shader_state *templ) 27089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 27189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct softpipe_context *softpipe = softpipe_context(pipe); 27289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct sp_geometry_shader *state; 27389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 27489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin state = CALLOC_STRUCT(sp_geometry_shader); 27589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (state == NULL ) 27689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin goto fail; 27789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 278ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin /* debug */ 279ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin if (softpipe->dump_gs) 280ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin tgsi_dump(templ->tokens, 0); 281ac96ee1c16419583aa43c9f4100aaca774b9439aZack Rusin 28289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin /* copy shader tokens, the ones passed in will go away. 28389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin */ 28489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin state->shader.tokens = tgsi_dup_tokens(templ->tokens); 28589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (state->shader.tokens == NULL) 28689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin goto fail; 28789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 28889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin state->draw_data = draw_create_geometry_shader(softpipe->draw, templ); 28989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (state->draw_data == NULL) 29089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin goto fail; 29189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 29253bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; 29353bd9796a1395e4acde884ff55cb7ee18586595aZack Rusin 29489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return state; 29589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 29689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinfail: 29789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (state) { 29889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE( (void *)state->shader.tokens ); 29989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE( state->draw_data ); 30089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE( state ); 30189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 30289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return NULL; 30389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 30489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 30589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 306279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 30789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_bind_gs_state(struct pipe_context *pipe, void *gs) 30889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 30989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct softpipe_context *softpipe = softpipe_context(pipe); 31089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 31189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin softpipe->gs = (struct sp_geometry_shader *)gs; 31289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 31389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw_bind_geometry_shader(softpipe->draw, 31489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin (softpipe->gs ? softpipe->gs->draw_data : NULL)); 31589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 31689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin softpipe->dirty |= SP_NEW_GS; 31789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 31889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 31989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 320279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 32189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinsoftpipe_delete_gs_state(struct pipe_context *pipe, void *gs) 32289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 32389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct softpipe_context *softpipe = softpipe_context(pipe); 32489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 32589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct sp_geometry_shader *state = 32689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin (struct sp_geometry_shader *)gs; 32789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 32842eefb8235437655632b36490f49a3a8fdc69401Zack Rusin draw_delete_geometry_shader(softpipe->draw, 32942eefb8235437655632b36490f49a3a8fdc69401Zack Rusin (state) ? state->draw_data : 0); 33089d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand 33189d6044b7b70304bdd9ebab734d8b1c0826cbdb8Morgan Armand FREE((void *) state->shader.tokens); 33289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE(state); 33389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 334279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 335279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 336279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulstatic void 337279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulsoftpipe_set_constant_buffer(struct pipe_context *pipe, 338279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul uint shader, uint index, 339507337864fa80caf9f26602324d2c28dd0a75d61Marek Olšák struct pipe_constant_buffer *cb) 340279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul{ 341279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul struct softpipe_context *softpipe = softpipe_context(pipe); 342507337864fa80caf9f26602324d2c28dd0a75d61Marek Olšák struct pipe_resource *constants = cb ? cb->buffer : NULL; 3430b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák unsigned size; 3440b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák const void *data; 3450b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák 3460b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák if (cb && cb->user_buffer) { 347b5752e16e82d4375171d157cb116a81ea025ea7bBrian Paul constants = softpipe_user_buffer_create(pipe->screen, 348b5752e16e82d4375171d157cb116a81ea025ea7bBrian Paul (void *) cb->user_buffer, 3490b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák cb->buffer_size, 3500b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák PIPE_BIND_CONSTANT_BUFFER); 3510b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák } 3520b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák 3530b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák size = constants ? constants->width0 : 0; 3540b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák data = constants ? softpipe_resource(constants)->data : NULL; 355279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 356279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul assert(shader < PIPE_SHADER_TYPES); 357279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 358279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul draw_flush(softpipe->draw); 359279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 360279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul /* note: reference counting */ 361279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe_resource_reference(&softpipe->constants[shader][index], constants); 362279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 363279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { 364279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); 365279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul } 366279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 367279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul softpipe->mapped_constants[shader][index] = data; 368279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul softpipe->const_buffer_size[shader][index] = size; 369279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 370279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul softpipe->dirty |= SP_NEW_CONSTANTS; 3710b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák 3720b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák if (cb && cb->user_buffer) { 3730b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák pipe_resource_reference(&constants, NULL); 3740b7d48cbad86eaac21fce3793da41b46db8be3b4Marek Olšák } 375279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul} 376279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 377279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 378279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulvoid 379279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paulsoftpipe_init_shader_funcs(struct pipe_context *pipe) 380279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul{ 381279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->create_fs_state = softpipe_create_fs_state; 382279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->bind_fs_state = softpipe_bind_fs_state; 383279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->delete_fs_state = softpipe_delete_fs_state; 384279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 385279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->create_vs_state = softpipe_create_vs_state; 386279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->bind_vs_state = softpipe_bind_vs_state; 387279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->delete_vs_state = softpipe_delete_vs_state; 388279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 389279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->create_gs_state = softpipe_create_gs_state; 390279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->bind_gs_state = softpipe_bind_gs_state; 391279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->delete_gs_state = softpipe_delete_gs_state; 392279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul 393279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul pipe->set_constant_buffer = softpipe_set_constant_buffer; 394279b368dc34d8829bfd23b83af7f78e10e303f54Brian Paul} 395