svga_shader.c revision af69d88d
1/********************************************************** 2 * Copyright 2008-2012 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26#include "util/u_bitmask.h" 27#include "util/u_memory.h" 28#include "svga_context.h" 29#include "svga_cmd.h" 30#include "svga_shader.h" 31 32 33 34/** 35 * Issue the SVGA3D commands to define a new shader. 36 * \param result contains the shader tokens, etc. The result->id field will 37 * be set here. 38 */ 39enum pipe_error 40svga_define_shader(struct svga_context *svga, 41 SVGA3dShaderType type, 42 struct svga_shader_variant *variant) 43{ 44 unsigned codeLen = variant->nr_tokens * sizeof(variant->tokens[0]); 45 46 if (svga_have_gb_objects(svga)) { 47 struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; 48 enum pipe_error ret; 49 50 variant->gb_shader = sws->shader_create(sws, type, 51 variant->tokens, codeLen); 52 if (!variant->gb_shader) 53 return PIPE_ERROR_OUT_OF_MEMORY; 54 55 ret = SVGA3D_BindGBShader(svga->swc, variant->gb_shader); 56 if (ret != PIPE_OK) { 57 sws->shader_destroy(sws, variant->gb_shader); 58 variant->gb_shader = NULL; 59 } 60 61 return ret; 62 } 63 else { 64 enum pipe_error ret; 65 66 /* Allocate an integer ID for the shader */ 67 variant->id = util_bitmask_add(svga->shader_id_bm); 68 if (variant->id == UTIL_BITMASK_INVALID_INDEX) { 69 return PIPE_ERROR_OUT_OF_MEMORY; 70 } 71 72 /* Issue SVGA3D device command to define the shader */ 73 ret = SVGA3D_DefineShader(svga->swc, 74 variant->id, 75 type, 76 variant->tokens, 77 codeLen); 78 if (ret != PIPE_OK) { 79 /* free the ID */ 80 assert(variant->id != UTIL_BITMASK_INVALID_INDEX); 81 util_bitmask_clear(svga->shader_id_bm, variant->id); 82 variant->id = UTIL_BITMASK_INVALID_INDEX; 83 return ret; 84 } 85 } 86 87 return PIPE_OK; 88} 89 90 91 92enum pipe_error 93svga_destroy_shader_variant(struct svga_context *svga, 94 SVGA3dShaderType type, 95 struct svga_shader_variant *variant) 96{ 97 enum pipe_error ret = PIPE_OK; 98 99 if (svga_have_gb_objects(svga)) { 100 struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; 101 102 sws->shader_destroy(sws, variant->gb_shader); 103 variant->gb_shader = NULL; 104 goto end; 105 } 106 107 /* first try */ 108 if (variant->id != UTIL_BITMASK_INVALID_INDEX) { 109 ret = SVGA3D_DestroyShader(svga->swc, variant->id, type); 110 111 if (ret != PIPE_OK) { 112 /* flush and try again */ 113 svga_context_flush(svga, NULL); 114 115 ret = SVGA3D_DestroyShader(svga->swc, variant->id, type); 116 assert(ret == PIPE_OK); 117 } 118 119 util_bitmask_clear(svga->shader_id_bm, variant->id); 120 } 121 122end: 123 FREE((unsigned *)variant->tokens); 124 FREE(variant); 125 126 return ret; 127} 128