1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009 Nicolai Haehnle. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_code.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h> 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h> 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_constants_init(struct rc_constant_list * c) 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(c, 0, sizeof(*c)); 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copy a constants structure, assuming that the destination structure 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is not initialized. 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_constants_copy(struct rc_constant_list * dst, struct rc_constant_list * src) 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Constants = malloc(sizeof(struct rc_constant) * src->Count); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dst->Constants, src->Constants, sizeof(struct rc_constant) * src->Count); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Count = src->Count; 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->_Reserved = src->Count; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_constants_destroy(struct rc_constant_list * c) 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(c->Constants); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(c, 0, sizeof(*c)); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned rc_constants_add(struct rc_constant_list * c, struct rc_constant * constant) 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index = c->Count; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Count >= c->_Reserved) { 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_constant * newlist; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->_Reserved = c->_Reserved * 2; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!c->_Reserved) 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->_Reserved = 16; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newlist = malloc(sizeof(struct rc_constant) * c->_Reserved); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(newlist, c->Constants, sizeof(struct rc_constant) * c->Count); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(c->Constants); 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Constants = newlist; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Constants[index] = *constant; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Count++; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Add a state vector to the constant list, while trying to avoid duplicates. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned rc_constants_add_state(struct rc_constant_list * c, unsigned state0, unsigned state1) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_constant constant; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(index = 0; index < c->Count; ++index) { 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].Type == RC_CONSTANT_STATE) { 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].u.State[0] == state0 && 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Constants[index].u.State[1] == state1) 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&constant, 0, sizeof(constant)); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Type = RC_CONSTANT_STATE; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Size = 4; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.u.State[0] = state0; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.u.State[1] = state1; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rc_constants_add(c, &constant); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Add an immediate vector to the constant list, while trying to avoid 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * duplicates. 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned rc_constants_add_immediate_vec4(struct rc_constant_list * c, const float * data) 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_constant constant; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(index = 0; index < c->Count; ++index) { 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) { 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!memcmp(c->Constants[index].u.Immediate, data, sizeof(float)*4)) 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&constant, 0, sizeof(constant)); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Type = RC_CONSTANT_IMMEDIATE; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Size = 4; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(constant.u.Immediate, data, sizeof(float) * 4); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rc_constants_add(c, &constant); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Add an immediate scalar to the constant list, while trying to avoid 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * duplicates. 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle) 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int free_index = -1; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_constant constant; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(index = 0; index < c->Count; ++index) { 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned comp; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(comp = 0; comp < c->Constants[index].Size; ++comp) { 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].u.Immediate[comp] == data) { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *swizzle = RC_MAKE_SWIZZLE_SMEAR(comp); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[index].Size < 4) 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free_index = index; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (free_index >= 0) { 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned comp = c->Constants[free_index].Size++; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Constants[free_index].u.Immediate[comp] = data; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *swizzle = RC_MAKE_SWIZZLE_SMEAR(comp); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return free_index; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&constant, 0, sizeof(constant)); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Type = RC_CONSTANT_IMMEDIATE; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.Size = 1; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constant.u.Immediate[0] = data; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *swizzle = RC_SWIZZLE_XXXX; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rc_constants_add(c, &constant); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_constants_print(struct rc_constant_list * c) 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < c->Count; i++) { 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Constants[i].Type == RC_CONSTANT_IMMEDIATE) { 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float * values = c->Constants[i].u.Immediate; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "CONST[%u] = " 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "{ %10.4f %10.4f %10.4f %10.4f }\n", 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i, values[0],values[1], values[2], values[3]); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 188