1/* 2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#ifndef _NINE_PIXELSHADER9_H_ 24#define _NINE_PIXELSHADER9_H_ 25 26#include "iunknown.h" 27#include "nine_shader.h" 28#include "nine_state.h" 29#include "basetexture9.h" 30#include "nine_ff.h" 31#include "surface9.h" 32 33struct nine_lconstf; 34 35struct NinePixelShader9 36{ 37 struct NineUnknown base; 38 struct nine_shader_variant variant; 39 40 struct { 41 const DWORD *tokens; 42 DWORD size; 43 uint8_t version; /* (major << 4) | minor */ 44 } byte_code; 45 46 uint8_t bumpenvmat_needed; 47 uint16_t sampler_mask; 48 uint8_t rt_mask; 49 50 boolean int_slots_used[NINE_MAX_CONST_I]; 51 boolean bool_slots_used[NINE_MAX_CONST_B]; 52 53 unsigned const_int_slots; 54 unsigned const_bool_slots; 55 56 struct nine_shader_constant_combination *c_combinations; 57 58 uint64_t ff_key[6]; 59 void *ff_cso; 60 61 uint64_t last_key; 62 void *last_cso; 63 unsigned *last_const_ranges; 64 unsigned last_const_used_size; /* in bytes */ 65 66 uint64_t next_key; 67}; 68static inline struct NinePixelShader9 * 69NinePixelShader9( void *data ) 70{ 71 return (struct NinePixelShader9 *)data; 72} 73 74static inline BOOL 75NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps, 76 struct nine_context *context ) 77{ 78 uint16_t samplers_shadow; 79 uint16_t samplers_fetch4; 80 uint16_t samplers_ps1_types; 81 uint8_t projected; 82 uint64_t key; 83 BOOL res; 84 85 samplers_shadow = (uint16_t)((context->samplers_shadow & NINE_PS_SAMPLERS_MASK) >> NINE_SAMPLER_PS(0)); 86 samplers_fetch4 = (uint16_t)((context->samplers_fetch4 & NINE_PS_SAMPLERS_MASK) >> NINE_SAMPLER_PS(0)); 87 key = samplers_shadow & ps->sampler_mask; 88 samplers_fetch4 &= ps->sampler_mask; 89 90 if (unlikely(ps->byte_code.version < 0x20)) { 91 /* variable targets */ 92 uint32_t m = ps->sampler_mask; 93 samplers_ps1_types = 0; 94 while (m) { 95 int s = ffs(m) - 1; 96 m &= ~(1 << s); 97 samplers_ps1_types |= (context->texture[s].enabled ? context->texture[s].pstype : 1) << (s * 2); 98 } 99 /* Note: For ps 1.X, only samplers 0 1 2 and 3 are available (except 1.4 where 4 and 5 are available). 100 * ps < 1.4: samplers_shadow 4b, samplers_ps1_types 8b, projected 8b 101 * ps 1.4: samplers_shadow 6b, samplers_ps1_types 12b 102 * Tot ps X.X samplers_shadow + extra: 20b */ 103 assert((ps->byte_code.version < 0x14 && !(ps->sampler_mask & 0xFFF0)) || !(ps->sampler_mask & 0xFFC0)); 104 105 if (unlikely(ps->byte_code.version < 0x14)) { 106 key |= samplers_ps1_types << 4; 107 projected = nine_ff_get_projected_key_programmable(context); 108 key |= ((uint64_t) projected) << 12; 109 } else { 110 key |= samplers_ps1_types << 6; 111 } 112 } 113 114 if (ps->byte_code.version < 0x30) { 115 key |= ((uint64_t)context->rs[D3DRS_FOGENABLE]) << 20; 116 key |= ((uint64_t)context->rs[D3DRS_FOGTABLEMODE]) << 21; 117 } 118 119 /* centroid interpolation automatically used for color ps inputs */ 120 if (context->rt[0]->base.info.nr_samples) 121 key |= ((uint64_t)1) << 22; 122 123 if ((ps->const_int_slots > 0 || ps->const_bool_slots > 0) && context->inline_constants) 124 key |= ((uint64_t)nine_shader_constant_combination_key(&ps->c_combinations, 125 ps->int_slots_used, 126 ps->bool_slots_used, 127 (void *)context->ps_const_i, 128 context->ps_const_b)) << 24; 129 130 key |= ((uint64_t)(context->rs[NINED3DRS_FETCH4] & samplers_fetch4)) << 32; 131 res = ps->last_key != key; 132 if (res) 133 ps->next_key = key; 134 return res; 135} 136 137void * 138NinePixelShader9_GetVariant( struct NinePixelShader9 *ps, 139 unsigned **const_ranges, 140 unsigned *const_used_size ); 141 142/*** public ***/ 143 144HRESULT 145NinePixelShader9_new( struct NineDevice9 *pDevice, 146 struct NinePixelShader9 **ppOut, 147 const DWORD *pFunction, void *cso ); 148 149HRESULT 150NinePixelShader9_ctor( struct NinePixelShader9 *, 151 struct NineUnknownParams *pParams, 152 const DWORD *pFunction, void *cso ); 153 154void 155NinePixelShader9_dtor( struct NinePixelShader9 * ); 156 157HRESULT NINE_WINAPI 158NinePixelShader9_GetFunction( struct NinePixelShader9 *This, 159 void *pData, 160 UINT *pSizeOfData ); 161 162#endif /* _NINE_PIXELSHADER9_H_ */ 163