17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom
97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */
227ec681f3Smrg
237ec681f3Smrg#ifndef _NINE_VERTEXSHADER9_H_
247ec681f3Smrg#define _NINE_VERTEXSHADER9_H_
257ec681f3Smrg
267ec681f3Smrg#include "util/half_float.h"
277ec681f3Smrg
287ec681f3Smrg#include "iunknown.h"
297ec681f3Smrg#include "device9.h"
307ec681f3Smrg#include "nine_helpers.h"
317ec681f3Smrg#include "nine_shader.h"
327ec681f3Smrg#include "nine_state.h"
337ec681f3Smrg
347ec681f3Smrgstruct NineVertexDeclaration9;
357ec681f3Smrg
367ec681f3Smrgstruct NineVertexShader9
377ec681f3Smrg{
387ec681f3Smrg    struct NineUnknown base;
397ec681f3Smrg    struct nine_shader_variant variant;
407ec681f3Smrg
417ec681f3Smrg    struct {
427ec681f3Smrg        uint16_t ndecl; /* NINE_DECLUSAGE_x */
437ec681f3Smrg    } input_map[PIPE_MAX_ATTRIBS];
447ec681f3Smrg    unsigned num_inputs;
457ec681f3Smrg
467ec681f3Smrg    struct {
477ec681f3Smrg        const DWORD *tokens;
487ec681f3Smrg        DWORD size;
497ec681f3Smrg        uint8_t version; /* (major << 4) | minor */
507ec681f3Smrg    } byte_code;
517ec681f3Smrg
527ec681f3Smrg    uint8_t sampler_mask;
537ec681f3Smrg
547ec681f3Smrg    boolean position_t; /* if true, disable vport transform */
557ec681f3Smrg    boolean point_size; /* if true, set rasterizer.point_size_per_vertex to 1 */
567ec681f3Smrg    boolean swvp_only;
577ec681f3Smrg
587ec681f3Smrg    struct nine_lconstf lconstf;
597ec681f3Smrg
607ec681f3Smrg    boolean int_slots_used[NINE_MAX_CONST_I];
617ec681f3Smrg    boolean bool_slots_used[NINE_MAX_CONST_B];
627ec681f3Smrg
637ec681f3Smrg    unsigned const_int_slots;
647ec681f3Smrg    unsigned const_bool_slots;
657ec681f3Smrg
667ec681f3Smrg    struct nine_shader_constant_combination *c_combinations;
677ec681f3Smrg
687ec681f3Smrg    uint64_t ff_key[3];
697ec681f3Smrg    void *ff_cso;
707ec681f3Smrg
717ec681f3Smrg    uint64_t last_key;
727ec681f3Smrg    void *last_cso;
737ec681f3Smrg    unsigned *last_const_ranges;
747ec681f3Smrg    unsigned last_const_used_size; /* in bytes */
757ec681f3Smrg
767ec681f3Smrg    uint64_t next_key;
777ec681f3Smrg
787ec681f3Smrg    /* so */
797ec681f3Smrg    struct nine_shader_variant_so variant_so;
807ec681f3Smrg};
817ec681f3Smrgstatic inline struct NineVertexShader9 *
827ec681f3SmrgNineVertexShader9( void *data )
837ec681f3Smrg{
847ec681f3Smrg    return (struct NineVertexShader9 *)data;
857ec681f3Smrg}
867ec681f3Smrg
877ec681f3Smrgstatic inline BOOL
887ec681f3SmrgNineVertexShader9_UpdateKey( struct NineVertexShader9 *vs,
897ec681f3Smrg                             struct NineDevice9 *device )
907ec681f3Smrg{
917ec681f3Smrg    struct nine_context *context = &(device->context);
927ec681f3Smrg    uint8_t samplers_shadow;
937ec681f3Smrg    uint64_t key;
947ec681f3Smrg    BOOL res;
957ec681f3Smrg
967ec681f3Smrg    samplers_shadow = (uint8_t)((context->samplers_shadow & NINE_VS_SAMPLERS_MASK) >> NINE_SAMPLER_VS(0));
977ec681f3Smrg    samplers_shadow &= vs->sampler_mask;
987ec681f3Smrg    key = samplers_shadow;
997ec681f3Smrg
1007ec681f3Smrg    if (vs->byte_code.version < 0x30)
1017ec681f3Smrg        key |= (uint32_t) ((!!context->rs[D3DRS_FOGENABLE]) << 8);
1027ec681f3Smrg    key |= (uint32_t) (context->swvp << 9);
1037ec681f3Smrg
1047ec681f3Smrg    if ((vs->const_int_slots > 0 || vs->const_bool_slots > 0) && context->inline_constants && !context->swvp)
1057ec681f3Smrg        key |= ((uint64_t)nine_shader_constant_combination_key(&vs->c_combinations,
1067ec681f3Smrg                                                               vs->int_slots_used,
1077ec681f3Smrg                                                               vs->bool_slots_used,
1087ec681f3Smrg                                                               context->vs_const_i,
1097ec681f3Smrg                                                               context->vs_const_b)) << 16;
1107ec681f3Smrg
1117ec681f3Smrg    /* We want to use a 64 bits key for performance.
1127ec681f3Smrg     * Use compressed float16 values for the pointsize min/max in the key.
1137ec681f3Smrg     * Shaders do not usually output psize.*/
1147ec681f3Smrg    if (vs->point_size) {
1157ec681f3Smrg        key |= ((uint64_t)_mesa_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MIN]))) << 32;
1167ec681f3Smrg        key |= ((uint64_t)_mesa_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MAX]))) << 48;
1177ec681f3Smrg    }
1187ec681f3Smrg
1197ec681f3Smrg    res = vs->last_key != key;
1207ec681f3Smrg    if (res)
1217ec681f3Smrg        vs->next_key = key;
1227ec681f3Smrg    return res;
1237ec681f3Smrg}
1247ec681f3Smrg
1257ec681f3Smrgvoid *
1267ec681f3SmrgNineVertexShader9_GetVariant( struct NineVertexShader9 *vs,
1277ec681f3Smrg                              unsigned **const_ranges,
1287ec681f3Smrg                              unsigned *const_used_size );
1297ec681f3Smrg
1307ec681f3Smrgvoid *
1317ec681f3SmrgNineVertexShader9_GetVariantProcessVertices( struct NineVertexShader9 *vs,
1327ec681f3Smrg                                             struct NineVertexDeclaration9 *vdecl_out,
1337ec681f3Smrg                                             struct pipe_stream_output_info *so );
1347ec681f3Smrg
1357ec681f3Smrg/*** public ***/
1367ec681f3Smrg
1377ec681f3SmrgHRESULT
1387ec681f3SmrgNineVertexShader9_new( struct NineDevice9 *pDevice,
1397ec681f3Smrg                       struct NineVertexShader9 **ppOut,
1407ec681f3Smrg                       const DWORD *pFunction, void *cso );
1417ec681f3Smrg
1427ec681f3SmrgHRESULT
1437ec681f3SmrgNineVertexShader9_ctor( struct NineVertexShader9 *,
1447ec681f3Smrg                        struct NineUnknownParams *pParams,
1457ec681f3Smrg                        const DWORD *pFunction, void *cso );
1467ec681f3Smrg
1477ec681f3Smrgvoid
1487ec681f3SmrgNineVertexShader9_dtor( struct NineVertexShader9 * );
1497ec681f3Smrg
1507ec681f3SmrgHRESULT NINE_WINAPI
1517ec681f3SmrgNineVertexShader9_GetFunction( struct NineVertexShader9 *This,
1527ec681f3Smrg                               void *pData,
1537ec681f3Smrg                               UINT *pSizeOfData );
1547ec681f3Smrg
1557ec681f3Smrg#endif /* _NINE_VERTEXSHADER9_H_ */
156